如何构建相互构建的鼻子单元测试?

时间:2011-07-11 22:33:08

标签: python unit-testing nose

实施例

假设您有一个假设的API,如下所示:

import foo

account_name = foo.register()
session = foo.login(account_name)
session.do_something()

关键点是,为了do_something(),您需要注册并登录。

这是一个过于简化的,第一遍的单元测试套件,可能会写:

# test_foo.py
import foo

def test_registration_should_succeed():
    foo.register()

def test_login_should_succeed():
    account_name = foo.register()
    foo.login(account_name)

def test_do_something_should_succeed():
    account_name = foo.register()
    session = foo.login(account_name)
    session.do_something()

问题

当注册失败时,所有测试都会失败,这使得它在哪里不明显 真正的问题是。看起来一切都坏了,但实际上只有一个关键的东西被打破了。除非你熟悉所有的测试,否则很难找到一件至关重要的事情。

问题

如何构建单元测试,以便在它们所依赖的核心功能失败时不执行后续测试?

以下是我想到的可行解决方案。

  1. 手动检测每个测试中的失败并引发SkipTest。 - 工作,但很多手动,容易出错的工作。
  2. 利用生成器在主要失败时不会产生后续测试。 - 不确定这是否真的有用(因为我怎么“知道”以前产生的测试失败了。)
  3. 将测试分组到测试类中。例如,这些是需要您登录的所有单元测试。 - 不确定这实际上解决了我的问题。会不会有那么多失败?

2 个答案:

答案 0 :(得分:4)

我认为更好的答案是使用mock objects,而不是回答明确的问题。通常,单元测试不应该要求访问外部数据库(可能需要登录)。但是,如果你想要进行一些集成测试( 一个好主意),那么那些测试应该测试集成方面,你的单元测试应该测试单位方面。我甚至会将集成测试和单元测试保存在单独的文件中,这样您就可以在非常的基础上快速运行单元测试,并且稍微少一点地运行集成测试定期(虽然至少每天一次)。

答案 1 :(得分:0)

这个问题表明Foo做得很多。你需要分开关注点。然后测试将变得容易。如果您有Registrator,LoginHandler和DoSomething类,以及编排工作流程的中央控制器类,那么所有内容都可以单独测试。