带有测试依赖的单元测试
当你有以下情况时,怎么进行单元测试呢?
- 一些普通的单元测试
- 一些更复杂的测试,用来检查边缘情况,这些测试依赖于普通的测试
举个例子,想象一下在测试一个CSV读取器(我随便编的一个例子),
def test_readCsv(): ...
@dependsOn(test_readCsv)
def test_readCsv_duplicateColumnName(): ...
@dependsOn(test_readCsv)
def test_readCsv_unicodeColumnName(): ...
我希望子测试只有在它的父测试成功时才会运行。这样做的原因是,运行这些测试需要时间。如果很多失败的报告都指向同一个原因,那也没什么意义。当然,我可以把所有的边缘情况都塞进主测试里,但我在想有没有更有条理的方法来处理这个。
我找到了一些相关但不同的问题,
更新:
我发现了 TestNG,它对测试依赖关系有很好的内置支持。你可以这样写测试,
@Test{dependsOnMethods = ("test_readCsv"))
public void test_readCsv_duplicateColumnName() {
...
}
6 个回答
2
我不太确定你指的是哪种语言(因为你在问题中没有具体提到),但像 PHPUnit 这样的工具有一个叫做 @depends 的标签,它只有在依赖的测试已经通过的情况下才会运行。
根据你使用的语言或单元测试工具,可能也会有类似的功能。
5
Proboscis 是一个用 Python 写的库,类似于 Java 里的 TestNG。
你可以在这里查看它的详细信息:packages.python.org/proboscis/
它支持依赖关系,比如:
@test(depends_on=[test_readCsv])
public void test_readCsv_duplicateColumnName() {
...
}
15
我个人觉得,不用太担心单元测试之间的依赖关系。这听起来有点像代码的坏味道。这里有几点想法:
- 如果一个测试失败了,那其他的测试也应该一起失败,这样你才能更好地了解问题的严重程度,看看代码改动带来了多大的影响。
- 测试失败应该是例外,而不是常态。所以没必要浪费时间去创建依赖关系,因为大多数情况下(希望如此!)这样做并没有什么好处。如果测试经常失败,问题不在于单元测试的依赖,而在于测试本身经常出错。
- 单元测试应该运行得非常快。如果测试运行得很慢,那就应该把精力放在提高测试速度上,而不是去防止后续的失败。可以通过让代码之间的关系更松散,使用依赖注入或模拟来实现这一点。