我看到很多问题都在问“如何”用一种特定的语言进行单元测试,但没有人问“什么”、“为什么”和“什么时候”。
是什么? 它对我有什么用? 我为什么要用它? 什么时候用(什么时候不用)? 有哪些常见的陷阱和误解
我看到很多问题都在问“如何”用一种特定的语言进行单元测试,但没有人问“什么”、“为什么”和“什么时候”。
是什么? 它对我有什么用? 我为什么要用它? 什么时候用(什么时候不用)? 有哪些常见的陷阱和误解
当前回答
我在大学里从未学过单元测试,我花了一段时间才“学会”它。我读到它,心想“啊,对,自动化测试,我想那应该很酷”,然后我就忘记了。
It took quite a bit longer before I really figured out the point: Let's say you're working on a large system and you write a small module. It compiles, you put it through its paces, it works great, you move on to the next task. Nine months down the line and two versions later someone else makes a change to some seemingly unrelated part of the program, and it breaks the module. Worse, they test their changes, and their code works, but they don't test your module; hell, they may not even know your module exists.
现在你有了一个问题:坏代码在主干中,甚至没有人知道。最好的情况是内部测试人员在您发布之前就发现了它,但是在游戏后期修复代码的成本很高。如果没有内部测试人员发现它……嗯,这确实会非常昂贵。
The solution is unit tests. They'll catch problems when you write code - which is fine - but you could have done that by hand. The real payoff is that they'll catch problems nine months down the line when you're now working on a completely different project, but a summer intern thinks it'll look tidier if those parameters were in alphabetical order - and then the unit test you wrote way back fails, and someone throws things at the intern until he changes the parameter order back. That's the "why" of unit tests. :-)
其他回答
我不反对丹的观点(尽管不回答可能是更好的选择)……但是……
单元测试是编写代码来测试系统的行为和功能的过程。
显然,测试可以提高代码的质量,但这只是单元测试的表面好处。真正的好处是:
Make it easier to change the technical implementation while making sure you don't change the behavior (refactoring). Properly unit tested code can be aggressively refactored/cleaned up with little chance of breaking anything without noticing it. Give developers confidence when adding behavior or making fixes. Document your code Indicate areas of your code that are tightly coupled. It's hard to unit test code that's tightly coupled Provide a means to use your API and look for difficulties early on Indicates methods and classes that aren't very cohesive
你应该进行单元测试,因为向客户交付可维护的高质量产品符合你的利益。
我建议您将它用于任何系统,或系统的一部分,以模拟真实世界的行为。换句话说,它特别适合于企业开发。我不会将它用于一次性/实用程序。我不会用它来测试系统中有问题的部分(UI是一个常见的例子,但并不总是这样)
最大的陷阱是开发人员测试太大的单元,或者他们认为一个方法是一个单元。如果您不理解控制反转,这一点尤其正确——在这种情况下,您的单元测试总是会变成端到端集成测试。单元测试应该测试单个行为——大多数方法都有许多行为。
最大的误解是程序员不应该测试。只有糟糕或懒惰的程序员才会相信这一点。给你盖屋顶的人不应该测试吗?更换心脏瓣膜的医生不应该检查新瓣膜吗?只有程序员才能测试他的代码是否按照他的意图去做(QA可以测试边缘情况——当代码被告知要做程序员不打算做的事情时,它的行为如何,而客户可以进行验收测试——代码是否按照客户的要求去做)
首先,无论是谈论单元测试还是其他类型的自动化测试(集成、加载、UI测试等),与您所建议的关键区别在于它是自动化的、可重复的,并且不需要消耗任何人力资源(=没有人需要执行测试,它们通常按下按钮就可以运行)。
单元测试是一种实践,以确保您将要实现的功能或模块的行为符合预期(需求),并确保它在边界条件和无效输入等场景下的行为。
xUnit, NUnit, mbUnit等都是帮助你编写测试的工具。
我使用单元测试来节省时间。
在构建业务逻辑(或数据访问)时,测试功能通常涉及在许多屏幕上输入内容,这些内容可能尚未完成,也可能尚未完成。自动化这些测试可以节省时间。
对我来说,单元测试是一种模块化的测试工具。每个公共函数通常至少有一个测试。我编写额外的测试来覆盖各种行为。
您在开发代码时想到的所有特殊情况都可以记录在单元测试的代码中。单元测试还成为如何使用代码的示例的来源。
对我来说,在单元测试中发现我的新代码破坏了某些东西比检入代码并让前端开发人员发现问题要快得多。
对于数据访问测试,我尝试编写没有更改或自行清理的测试。
单元测试不能解决所有的测试需求。他们将能够节省开发时间并测试应用程序的核心部分。
单元测试和TDD通常能让你对所编写的软件有更短的反馈周期。与在实现的最后有一个大型测试阶段不同,您可以增量地测试您所编写的所有内容。这大大提高了代码质量,正如您立即看到的那样,您可能会有错误。