单元测试与验收测试
你支持其中之一吗?或者两者都有?
我的理解是单元测试:
- 从开发人员的角度验证系统
- 帮助开发人员实践TDD
- 保持代码模块化
- 协助检测低粒度的错误
验收测试:
- 从业务和QC / QA的角度验证系统
- 往往是高水平,因为它们通常是由不熟悉代码内部工作原理的人编写的,
我认为两者都是必要的。然而,为了最大限度地减少冗余工作,尝试将单元测试纳入验收测试是一个好主意吗?换句话说,让后者调用前者。朝相反的方向前进还有意义吗?
您对单元测试与验收测试的总体看法是什么,以及如何管理它们之间的关系?
Are you for one or the other? Or both?
My understanding is unit tests:
- validate the system from the developer's point of view
- help developers practice TDD
- keep code modular
- assist in detecting errors at low levels of granularity
Acceptance tests:
- validate the system from the business and QC / QA points of view
- tend to be high level as they're often written by people not familiar with the inner workings of the code
I feel both are necessary. However, for minimization of redundant work, is it a good idea to try to incorporate unit tests into acceptance tests? In other words, have the latter call the former. Does going in the opposite direction make any sense?
What are your thoughts in general on unit tests vs. acceptance tests, and how to manage them in relation to each other?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
验收和集成测试会告诉您代码是否有效且完整;单元测试会告诉你哪里失败了。
如果您在验收和集成测试方面做得很好,并且它们通过了,那么您的代码正在实现它应该实现的所有功能,并且它正在工作。很高兴知道这一点(也很高兴知道事实并非如此)。但如果它不起作用,验收测试不会让你深入了解哪里出了问题;由于它测试了许多功能单元,因此它可以是失败的鸟瞰图。这就是单元测试的亮点。好的单元测试可以准确地告诉您出了什么问题,以及代码的哪一部分。与验收测试相比,了解您是否编写了足够的单元测试更难,但是当您的验收测试失败而没有相应的失败单元测试时 - 是时候编写该单元测试了。
这都是从测试角度来看的。当然,TDD 不是(ATDD 也不是)测试。在推动您的设计方面,验收测试为您提供了一个广泛的路线图(“这就是您想去的地方”),而单元测试则将您带到下一个十字路口(“左转”)。它们在这方面都很有价值,而且它们的价值又是相辅相成的。
不要混淆它们;不要让他们混血。特别是单元测试不应该依赖于其他任何东西,并且通过使验收测试依赖于它们来限制单元测试将是错误的。当然他们可以共享一些框架代码,但是他们应该是独立的。
Acceptance and integration tests tell you whether your code is working and complete; unit tests tell you where it's failing.
If you've done a good job with acceptance and integration tests, and they're passing, your code is implementing all the functionality it's supposed to, and it's working. That's great to know (it's also great to know that it isn't). But if it isn't working, an acceptance test won't give you much insight into what has gone wrong; since it tests many units of functionality, it can be kind of a bird's-eye view of failure. This is where unit tests shine. Good unit tests tell you exactly what went wrong, with exactly what part of your code. It's harder to know whether you've written enough unit tests than acceptance tests, but when you have a failing acceptance test without a corresponding failing unit test - it's time to write that unit test.
That is all from the testing perspective. And, of course, TDD isn't (and ATDD isn't) about testing. With respect to driving your design, acceptance tests give you a broad roadmap ("here's where you want to go") while unit tests take you to the next intersection ("turn left"). They're both valuable in this regard and, again, their value complement one another.
Don't confuse them; don't miscegenate them. Unit tests, in particular, shouldn't depend on anything else, and it would be a mistake to constrain your unit tests by making acceptance test dependent on them. Of course they can share some framework code, but they should be independent.
作为上述所有内容的总结,
As a summary of all the above,
不。
别打扰。
验收测试通常是政治性的。你把它们展示给那些基于直觉决定接受或拒绝的人。
然后你们争论验收测试的有效性。
然后你们争论工作范围和下一个版本。
一般来说,验收测试不是技术性的。如果是的话,那么您将进行正式的单元测试,仅此而已。
不要试图玩弄政治。拥抱它。让它发生吧。
您可以希望验收测试驱动开发 (ATDD) 能够实现“在开发开始之前,整个团队编写并同意验收测试”。但你必须反映这样一个现实:任何提前写好的东西往好里说都是似是而非的,往坏里说是可以协商的。
所有敏捷方法背后的前提是您只能同意获得可发布的东西。之后的一切都是可以商量的。
所有测试优先(TDD、ATDD 或其他)背后的前提是测试是铁定的协议。但事实并非如此。对于任何 TDD(或 ATDD)方法,您原则上都可以同意测试结果,但您尚未真正同意测试本身。
可能会出现测试不容易编写的情况。或者更糟糕的是,根本无法写。您可能会同意似乎可测试的结果,但结果却是定义不明确。现在怎么办?在开始开发并了解细节之前,您无法了解这些事情。
所有测试都很重要。并且任何特定类型的测试都不能是任何其他类型测试的超集或子集。它们总是部分重叠的集合。试图结合起来以某种方式节省一些工作可能会被证明是浪费时间。
更多的测试比什么都好。所有测试的联合比尝试在测试之间强制建立子集-超集关系更有价值。
No.
Don't bother.
Acceptance tests are often political. You show them to people who -- based on their gut instinct -- decide to accept or reject.
Then you argue about the validity of the acceptance tests.
Then you argue about the scope of work and the next release.
Acceptance tests aren't -- generally -- technical. If they were, then you'd have formal unit tests and that would be that.
Don't try to finesse the politics. Embrace it. Let it happen.
You can hope that Acceptance Test-Driven Development (ATDD) leads to "acceptance tests are written and agreed upon by the entire team before development begins." But you have to reflect the reality that anything written in advance is specious at best and negotiable at worst.
The premise behind all Agile methods is that you can only agree to get to something releasable. Everything after that is negotiable.
The premise behind all test-first (TDD, ATDD, or anything else) is that a test is an iron-clad agreement. Except it's not. With any TDD (or ATDD) method you can agree -- in principle -- to the test results, but you haven't really agreed to the test itself.
It may arise that the test cannot easily be written. Or worse, cannot be written at all. You may agree to results that seem testable, but turn out to be poorly-defined. What now? These are things you can't know until you start development and get to details.
All testing is important. And no particular kind of testing can be a superset or subset of any other kind testing. They're always partially overlapping sets. Trying to combine to somehow save some work is likely to turn out to be a waste of time.
More testing is better than anything else. The union of all tests has more value than trying to force a subset-superset relationship among tests.
单元测试 - 我的特定功能完成了它应该做的事情,仅此而已。
验收测试 - 我的应用程序做了它应该做的事情。
示例:计算二次函数根的应用程序。接受 a、b 和 c 的输入,返回根 x1 和 x2。该应用程序是由我编写的函数构建的,用于将两个数字相加、两个数字相减、两个数字相乘、两个数字相除以及对两个数字求平方根。
单元测试 - 检查我的除法和乘法函数是否正常工作,我的平方根是否正常工作,我的加法和减法是否正常工作。
验收测试 - 检查我的应用程序是否计算二次函数的根。
由于我的整个应用程序是计算根,因此我不应该有一个也计算根的单元测试,因为没有单独的函数可以这样做。
Unit Tests - my specific function does what it's supposed to do, nothing more, and nothing less.
Acceptance Test - my application does what it's supposed to do.
Example: Application to calculate roots of quadratic functions. Takes inputs of a, b, and c, returns roots x1 and x2. This application is built by functions I write to add two numbers, subtract two numbers, multiply two numbers, divide two numbers, and take the square root of two numbers.
Unit tests - check that my divide and multiply functions work correctly, my square root works correctly, my add and subtract work correctly.
Acceptance tests - check that my application calculates roots of quadratic functions.
Since my entire application is to calculate roots, I should not have a unit test that also calculates roots because there is no individual function which does so.
以下只是我个人对某些测试问题的看法:
我赞同 S. Lott 对此的反对,并补充说,这里存在单元测试在某种程度上被操纵的危险,可能会产生一些错误。例如,在下拉菜单中,有人可能会测试一些状态,但可能不是全部,测试人员可能会使用不同的数据来发现潜在的错误。
我会小心地将它们耦合在一起。单元测试代表对最小功能的测试,通常非常小,以至于最终用户无法理解可能有数百个测试只是为了获得一个 Web 表单以将数据输入 CRM 系统。验收测试更多的是关于应用程序的用户想要什么,这可能更加主观,例如“这看起来漂亮吗?”与“这看起来合适吗?”验收测试可能会有“足够好”的标记,但我不确定是否适用于单元测试。通常,如果单元测试失败,则必须有人决定修复代码或删除测试,因为根据具体情况,每个测试都可能是一个不错的选择。
单元测试是为了验证最简单的代码片段。可以进行集成测试,但这是一个更高的级别,因为一旦检查了所有的小部件,这些部件的组合是否可以一起工作,例如,我小时候看过的周六早上的动画片有可以组合在一起的玩具,例如“战神金刚”或各种变形金刚,例如组成毁灭者的构造者。验收测试通常从最终用户的角度出发,“我现在可以对应用程序执行 X 操作吗?”在事情发生之前就得到“是”的回答。虽然可以在验收测试中检查一些错误情况,但对可以进入应用程序的每种可能的组合进行彻底的测试并不常见。然而,单元测试可能涵盖边界条件和一些其他类似随机的情况。
These are just my personal opinion on the issue of some kinds of tests:
I'd second S. Lott's no on this and add that there is a danger here of the unit tests being rigged to some extent that may have some bugs pass through. For example, on a drop down someone may test a few states but likely not all of them, where a tester may use different data to uncover a potential bug.
I'd be careful of ever coupling them together. The unit tests represent tests of the smallest bits of functionality, often so small that an end-user wouldn't understand that there may be hundreds of tests just to get a web form to enter data into a CRM system. Acceptance tests are more about what the user of the application wants which can be more subjective,e.g. "Does this look pretty?" versus "Does this look right?" There can be that mark of "good enough" with acceptance tests that I'm not sure would work with unit tests. Generally if a unit test fails, then someone has to decide either to fix the code or remove the test as each can be a good option depending on circumstance.
Unit tests are about verifying the simplest pieces of code. There can be integration tests but this is a level higher as once all the little pieces are checked, do the combination of the pieces work together,e.g. there were Saturday morning cartoons I watched growing up that had toys one could put together like "Voltron" or various Transformers like the Constructicons that formed Devastator. Acceptance tests are generally from an end user perspective of, "Can I do X with the application now?" having an answer of "Yes," before something goes out the door. While some error cases may be checked in an acceptance test, it isn't common to do a thorough test of every possible combination that one could enter into an application. However, unit tests may cover boundary conditions and a few other random-like cases.