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

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


当前回答

使用Testivus。你需要知道的都在那里:)

其他回答

测试驱动开发在某种程度上取代了单元测试这个术语。作为一个老手,我会提到它的更一般的定义。

单元测试还意味着测试一个较大系统中的单个组件。这个组件可以是dll、exe、类库等。它甚至可以是多系统应用程序中的单个系统。因此,单元测试最终是对一个更大系统的单个部分进行测试。

然后,您可以通过测试所有组件如何一起工作来进行集成测试或系统测试。

单元测试与“只是打开一个新项目并测试这个特定的代码”的主要区别在于它是自动化的,因此是可重复的。

如果您手动测试代码,它可能会使您相信代码在当前状态下工作得很完美。但一周后,当你对它做了轻微的修改时呢?您是否愿意在代码发生任何更改时再次手工重新测试?很可能不会:-(

但是,如果您可以在任何时间运行您的测试,只需单击一下,以完全相同的方式,在几秒钟内,那么一旦有什么东西坏了,它们就会立即显示给您。如果您还将单元测试集成到您的自动化构建过程中,即使在看似完全无关的更改破坏了代码库中遥远部分的某些情况下,它们也会提醒您错误——当您甚至不会想到需要重新测试特定的功能时。

这是单元测试相对于手工测试的主要优势。但等等,还有更多:

unit tests shorten the development feedback loop dramatically: with a separate testing department it may take weeks for you to know that there is a bug in your code, by which time you have already forgotten much of the context, thus it may take you hours to find and fix the bug; OTOH with unit tests, the feedback cycle is measured in seconds, and the bug fix process is typically along the lines of an "oh sh*t, I forgot to check for that condition here" :-) unit tests effectively document (your understanding of) the behaviour of your code unit testing forces you to reevaluate your design choices, which results in simpler, cleaner design

反过来,单元测试框架使您更容易编写和运行测试。

这回答了为什么您应该进行单元测试。


下面的三个视频涵盖了javascript中的单元测试,但一般原则适用于大多数语言。

单元测试:现在的几分钟将节省几小时后- Eric Mann - https://www.youtube.com/watch?v=_UmmaPe8Bzc

JS单元测试(非常好)- https://www.youtube.com/watch?v=-IYqgx8JxlU

编写可测试的JavaScript - https://www.youtube.com/watch?v=OzjogCFO4Zo


Now I'm just learning about the subject so I may not be 100% correct and there's more to it than what I'm describing here but my basic understanding of unit testing is that you write some test code (which is kept separate from your main code) that calls a function in your main code with input (arguments) that the function requires and the code then checks if it gets back a valid return value. If it does get back a valid value the unit testing framework that you're using to run the tests shows a green light (all good) if the value is invalid you get a red light and you then can fix the problem straight away before you release the new code to production, without testing you may actually not have caught the error.

So you write tests for you current code and create the code so that it passes the test. Months later you or someone else need to modify the function in your main code, because earlier you had already written test code for that function you now run again and the test may fail because the coder introduced a logic error in the function or return something completely different than what that function is supposed to return. Again without the test in place that error might be hard to track down as it can possibly affect other code as well and will go unnoticed.


Also the fact that you have a computer program that runs through your code and tests it instead of you manually doing it in the browser page by page saves time (unit testing for javascript). Let's say that you modify a function that is used by some script on a web page and it works all well and good for its new intended purpose. But, let's also say for arguments sake that there is another function you have somewhere else in your code that depends on that newly modified function for it to operate properly. This dependent function may now stop working because of the changes that you've made to the first function, however without tests in place that are run automatically by your computer you will not notice that there's a problem with that function until it is actually executed and you'll have to manually navigate to a web page that includes the script which executes the dependent function, only then you notice that there's a bug because of the change that you made to the first function.

重申一下,在开发应用程序时运行测试将在编写代码时发现这类问题。如果没有适当的测试,你必须手动检查整个应用程序,即使这样也很难发现错误,你天真地将其发送到生产环境中,一段时间后,好心的用户会给你发送错误报告(这不会像你在测试框架中的错误消息那样好)。


It's quite confusing when you first hear of the subject and you think to yourself, am I not already testing my code? And the code that you've written is working like it is supposed to already, "why do I need another framework?"... Yes you are already testing your code but a computer is better at doing it. You just have to write good enough tests for a function/unit of code once and the rest is taken care of for you by the mighty cpu instead of you having to manually check that all of your code is still working when you make a change to your code.

此外,如果你不想进行单元测试,你也不必进行单元测试,但随着你的项目/代码库开始变得越来越大,引入错误的可能性也在增加,这是值得的。

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

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

在单元测试和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 :)

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