我很难理解为什么在我见过的大多数专业 TDD 代码中每个函数只有一个测试
当您说“测试”时,我假设您的意思是“断言”。一般来说,一个测试应该只测试一个函数的一个“用例”。我所说的“用例”是指:代码可以通过控制流语句流过的路径(不要忘记处理的异常等)。本质上,您正在测试该功能的所有“要求”。例如,假设您有一个函数,例如:
Public Function DoSomething(ByVal foo as Boolean) As Integer
Dim result as integer = 0
If(foo) then
result = MakeRequestToWebServiceA()
Else
result = MakeRequestToWebServiceB()
End If
return result
End Function
在这种情况下,该函数可以采用 2 个“用例”或控制流。这个函数应该至少有 2 次测试。一种接受 foo 为 true 并向下分支 if(true) 代码,另一种接受 foo 为 false 并向下分支。如果您有更多 if 语句或流程,则代码可以运行,那么它将需要更多测试。这有几个原因 - 对我来说最重要的一个是没有它,测试将太复杂且难以阅读。还有其他原因,比如上面的函数,控制流是基于输入参数的——这意味着你必须调用函数两次来测试所有的代码路径。在您的测试 IMO 中进行测试时,您永远不应调用该函数。
但我发现自己很难想出函数名称来区分不同的测试,因为许多测试非常相似
也许你想多了??不要害怕为您的测试函数编写疯狂的、过于冗长的名称。无论该测试做什么,都用英文编写,使用下划线,并提出一套名称标准,以便其他人(包括 6 个月后的您自己)可以轻松地弄清楚它的作用。请记住,您实际上不必自己调用此函数(至少在大多数测试框架中),所以谁在乎它的名称是否为 100 个字符。疯了。在上面的示例中,我的 2 个测试将被命名为:
DoSomethingTest_TestWhenFooIsTrue_RequestIsMadeToWebServiceA()
DoSomethingTest_TestWhenFooIsFalse_RequestIsMadeToWebServiceB()
另外 - 这只是一般准则。肯定有在同一个单元测试中有多个断言的情况。这将在您测试 same 控制流时发生,但在您编写断言语句时需要检查多个字段。以这个为例 - 一个函数的测试,它将一个 CSV 文件解析为一个具有 Header、Body 和 Footer 字段的业务对象:
Public Sub ParseFileTest_TestFileIsParsedCorrectly()
Dim target as new FileParser()
Dim actual as SomeBusinessObject = target.ParseFile(TestHelper.GetTestData("ParseFileTest.csv")))
Assert.Equals(actual.Header,"EXPECTED HEADER FROM TEST DATA FILE")
Assert.Equals(actual.Footer,"EXPECTED FOOTER FROM TEST DATA FILE")
Assert.Equals(actual.Body,"TEST DATA BODY")
End Sub
在这里,我们实际上是在测试同一个用例,但我们需要多个断言来检查所有数据并确保我们的代码确实有效。
-画了