我想知道那些记录单元测试如何记录它的人。据我所知,大多数TDD粉丝声称“代码说话”,因此测试文档不是很重要,因为代码应该是自我描述的。很公平,但我想知道如何来记录单元测试,而不是是否来记录它们。
我作为开发人员的经历告诉我,理解旧代码(包括单元测试)很困难。
那么在测试文档中重要的是什么?何时测试方法名称的描述性不够,以便证明文档合理?
答案 0 :(得分:11)
根据Thorsten79的要求,我将详细阐述我的评论作为答案。我原来的评论是:
不幸的是,“代码说话” 完全错了,因为一个 非开发人员无法读取代码, 虽然他至少可以部分阅读 并了解生成 文档,这样他就可以 知道测试测试的内容。这是 特别重要的是 客户完全理解 域,只是无法读取代码,和 在单位时变得更加重要 测试也测试硬件,如在 嵌入式世界,因为那时你测试 可以看到的东西。
当你进行单元测试时,你必须知道你是为你(或同事)写的,还是你也是为别人写的。很多时候,您应该为您的读者编写代码,而不是为了您的方便。
在我公司的混合硬件/软件开发中,客户知道他们想要什么。如果他们的现场设备在接收某个总线命令时必须进行复位,则必须有一个单元测试发送该命令并检查设备是否被重置。我们现在正在这里使用NUnit作为单元测试框架,以及一些可以发送和接收命令(甚至按下按钮)的自定义软件和硬件。这很棒,因为唯一的选择就是手动完成所有操作。
客户绝对想知道哪些测试,他甚至想自己运行测试。如果没有正确记录测试,他不知道测试做了什么,也无法检查他认为他需要的所有测试是否存在,并且在运行测试时,他不知道它会做什么。 因为他无法读取代码。他比我们的开发人员更了解所使用的总线系统,但他们无法读取代码。如果测试失败,他不知道为什么甚至不能说他认为测试应该做什么。这不是一件好事。
正确记录单元测试后,我们
在此上下文中正确表示:编写非开发人员可以理解的清晰语言。你可以保持技术,但不要只写你能理解的东西。对于任何其他评论和任何代码,后者当然也很重要。
独立于我们的确切情况,我认为这是我在单元测试中一直想要的,即使它们是纯软件。客户可以忽略他不关心的单元测试,例如基本功能测试。但只是拥有那里的文档永远不会受到伤害。
正如我在评论中写到另一个答案:此外,如果您(或您的老板,同事或测试部门)想要检查哪些测试是,那么生成的文档也是一个很好的起点在那里和他们做了什么,因为你可以浏览它而不需要挖掘代码。
答案 1 :(得分:4)
在测试代码中:
使用方法级别的注释进行解释 测试/覆盖测试的内容。
在类级别,一个注释指示正在测试的实际类(实际上可以从测试类名称中推断出来,因此实际上不如方法级别的注释重要)。
使用测试覆盖率报告
答案 2 :(得分:3)
首先评论复杂测试或方案(如果需要,但支持可读测试)。
另一方面,我尝试让我的测试说明一切。换句话说:
[Test]
public void person_should_say_hello() {
// Arrange.
var person = new Person();
// Act.
string result = person.SayHello();
// Assert.
Assert.AreEqual("Hello", result, "Person did not say hello");
}
如果我要查看这个测试,我会看到它使用Person(虽然它会在PersonTest.cs
中作为线索;))然后如果有任何中断,它将发生在SayHello
方法。断言消息也很有用,不仅用于读取测试,而且在运行测试时,更容易在GUI中看到它们。
遵循AAA样式的Arrange,Act和Assert使测试基本上记录了自己。如果这个测试更复杂,你可以在测试函数上面添加注释来解释发生了什么。与往常一样,您应该确保这些保持最新。
作为旁注,对测试名称使用下划线表示法使它们更易于阅读,将其与以下内容进行比较:
public void PersonShouldSayHello()
对于长方法名称,可以使阅读测试更加困难。虽然这一点通常是主观的。
答案 3 :(得分:1)
当我回到旧测试并且不能立即理解时
当您编写测试用例时,它与您编写代码时的情况相同,每个人都非常清楚。这使得很难想象你应该写什么来使代码更清晰。
请注意,此并不代表我从不撰写任何评论。当我知道我将很难弄清楚特定代码片段的作用时,仍有很多情况。
在这些情况下,我通常从第1点开始......
答案 4 :(得分:1)
将单元测试改进为可执行规范是Behaviour-Driven Development的要点:BDD是TDD的演变,其中单元测试使用Ubiquitous Language(一种基于业务领域并由开发人员共享的语言)和利益相关者)和富有表现力的名称( testCannotCreateDuplicateEntry )来描述代码应该做什么。一些BDD框架推动了这个想法,并用example显示用几乎自然语言编写的可执行文件。
答案 5 :(得分:0)
我建议不要与代码分开的任何详细的文档。为什么?因为无论什么时候需要它,它很可能非常过时。详细文档的最佳位置是代码本身(包括注释)。顺便说一下,关于特定单元测试所需的任何内容都是非常详细的文档。
关于如何实现良好的自我记录测试的一些指示:
您应该在每个测试名称中包括:正在测试的内容,测试中的情况以及预期的行为。例如:test__getAccountBalance__NullAccount__raisesNullArgumentException()
将常用逻辑提取到具有描述性名称的设置/拆卸或辅助方法中。
并补充其他答案所说的内容:
如果您的客户/产品负责人/老板非常了解应该测试什么并且渴望提供帮助,那就太棒了,但是单元测试不是不是最好的地方它。 您应该使用验收测试。
单元测试应该涵盖特定的代码单元(类/模块中的方法/功能),如果你覆盖更多的地面,它们将很快变成集成测试,这很好并且也需要,但如果你不需要将它们分开,人们会让他们感到困惑,你将失去单元测试的一些好处。例如,当单元测试失败时,您应该立即检测到错误(特别是如果您遵循上面的命名约定)。当集成测试失败时,您知道存在问题,并且您知道它的一些影响,但您可能需要调试(有时很长一段时间)来查找它是什么。
如果需要,可以使用单元测试框架进行集成测试,但是您应该知道自己没有进行单元测试,并且应该将它们保存在单独的文件/目录中。
有很好的接受/行为测试框架(FitNesse,Robot,Selenium,Cucumber等)可以帮助业务/域名人员不仅阅读,还可以自己编写测试。当然,他们需要编码员的帮助才能让他们工作(特别是在开始时),但是他们能够做到这一点,而且他们不需要了解你的模块或功能类别。
< / LI>