2

例子

假设您有一个这样的假设 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. 将测试分组到测试类中。例如,这些都是需要您登录的所有单元测试。 - 不确定这是否真的解决了我的问题。不会有同样多的失败吗?
4

2 回答 2

4

与其回答明确的问题,我认为更好的答案是使用模拟对象。一般来说,单元测试不应该需要访问外部数据库(据推测需要登录)。但是,如果您想进行一些集成测试(这一个好主意),那么这些测试应该测试集成方面,而您的单元测试应该测试单元方面。我什至会将集成测试和单元测试保存在单独的文件中,这样您就可以非常定期地快速运行单元测试,并且稍微不定期地运行集成测试(尽管仍然至少一天一次)。

于 2011-07-11T23:06:24.910 回答
0

这个问题表明 Foo 做了很多事情。你需要分离关注点。然后测试将变得容易。如果您有一个 Registrator、一个 LoginHandler 和一个 DoSomething 类,再加上一个协调工作流程的中央控制器类,那么一切都可以单独测试。

于 2011-07-12T09:29:33.070 回答