我看到很多问题都在问“如何”用一种特定的语言进行单元测试,但没有人问“什么”、“为什么”和“什么时候”。

是什么? 它对我有什么用? 我为什么要用它? 什么时候用(什么时候不用)? 有哪些常见的陷阱和误解


当前回答

如果给你一堆垃圾,你似乎陷入了一种永久的清理状态,你知道任何新功能或代码的添加都会破坏当前的设置,因为当前的软件就像一个纸牌屋,你会怎么做? 那么我们如何进行单元测试呢?

从小事开始。我刚加入的项目直到几个月前才开始进行单元测试。当覆盖率如此之低时,我们将简单地选择一个没有覆盖率的文件并单击“添加测试”。

现在我们已经达到了40%以上,我们已经成功地摘走了大部分容易摘到的果实。

(最好的部分是,即使在这样低的覆盖率水平上,我们已经遇到了许多代码做错误事情的实例,并且测试发现了它。这是促使人们增加更多测试的巨大动力。)

其他回答

我不反对丹的观点(尽管不回答可能是更好的选择)……但是……

单元测试是编写代码来测试系统的行为和功能的过程。

显然,测试可以提高代码的质量,但这只是单元测试的表面好处。真正的好处是:

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可以测试边缘情况——当代码被告知要做程序员不打算做的事情时,它的行为如何,而客户可以进行验收测试——代码是否按照客户的要求去做)

我在大学里从未学过单元测试,我花了一段时间才“学会”它。我读到它,心想“啊,对,自动化测试,我想那应该很酷”,然后我就忘记了。

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. :-)

我想推荐Gerard Meszaros的《xUnit测试模式》一书。它很大,但在单元测试方面是一个很好的资源。这里有一个链接到他的网站,在那里他讨论了单元测试的基础知识。http://xunitpatterns.com/XUnitBasics.html

在单元测试和TDD的哲学优势方面,这里有一些关键的“灯泡”观察,这些观察在我试探性地走上TDD启蒙之路的第一步时打动了我(没有原创或一定是新闻)……

TDD does NOT mean writing twice the amount of code. Test code is typically fairly quick and painless to write and is a key part of your design process and critically. TDD helps you to realize when to stop coding! Your tests give you confidence that you've done enough for now and can stop tweaking and move on to the next thing. The tests and the code work together to achieve better code. Your code could be bad / buggy. Your TEST could be bad / buggy. In TDD you are banking on the chances of BOTH being bad / buggy being fairly low. Often its the test that needs fixing but that's still a good outcome. TDD helps with coding constipation. You know that feeling that you have so much to do you barely know where to start? It's Friday afternoon, if you just procrastinate for a couple more hours... TDD allows you to flesh out very quickly what you think you need to do, and gets your coding moving quickly. Also, like lab rats, I think we all respond to that big green light and work harder to see it again! In a similar vein, these designer types can SEE what they're working on. They can wander off for a juice / cigarette / iphone break and return to a monitor that immediately gives them a visual cue as to where they got to. TDD gives us something similar. It's easier to see where we got to when life intervenes... I think it was Fowler who said: "Imperfect tests, run frequently, are much better than perfect tests that are never written at all". I interprete this as giving me permission to write tests where I think they'll be most useful even if the rest of my code coverage is woefully incomplete. TDD helps in all kinds of surprising ways down the line. Good unit tests can help document what something is supposed to do, they can help you migrate code from one project to another and give you an unwarranted feeling of superiority over your non-testing colleagues :)

这篇演讲很好地介绍了测试所需要的所有内容。

如果你想使用Kent Beck推广的TDD方法开发项目,像NUnit、xUnit或JUnit这样的库是必须的:

你可以阅读《测试驱动开发介绍》(TDD)或Kent Beck的《测试驱动开发:举例说明》。

然后,如果你想确保你的测试覆盖了代码中“好的”部分,你可以使用NCover、JCover、PartCover或其他软件。它们会告诉你代码的覆盖率。取决于你对TDD的熟练程度,你会知道你是否已经很好地练习了它:)