在第三方 API 的行为很大程度上未知的情况下,推迟单元测试直到集成测试通过是否明智?
我并不是说推迟所有单元测试直到集成测试通过。我指的单元测试是那些验证 SUT 是否与第 3 方神秘 API 正确交互的单元测试。
推迟这些单元测试的理由是它们验证未知的东西。如果我不知道第 3 方神秘 API 是如何工作的,我如何编写单元测试来确保 SUT 正确使用第 3 方 API?只有通过一些最小的集成测试后,我才真正知道要验证哪些行为。
当然,所有其他单元测试都应该在以通常的方式(红色、绿色、重构)编写 SUT 之前编写。
I don't mean defer all unit-testing until an integration test passes. The unit tests I'm referring to are those that verify that the SUT interacts with the 3rd-party mystery API correctly.
The rationale for deferring these unit tests is that they verify something that is unknown. If I don't know how the 3rd-party mystery API works, how can I even write a unit test to ensure that the SUT uses the 3rd-party API correctly? Only once some minimal integration tests pass do I actually know what behavior to verify.
Of course, all other unit tests should be written before the SUT is written in the usual way (red, green, refactor).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
假设它是一个外部 api,我认为你的测试可能不符合单元测试的条件。他们将是集成测试。
编写一个模拟来按原样测试您的代码,然后在可以访问第 3 方 api 时编写适当的集成测试怎么样?另外,如果您正在对第三方内容进行单元测试,那么一旦这些内容不可用,您的构建就会失败,从长远来看,这可能会成为一个问题。
Under the assumption that it's an external api I'd argure that your tests probably wouldn't qualify as a unit test anyway. They'd be integration tests.
How about writing a mock to test your code as is and then writing proper integration tests when you can access the 3rd party api? Also, if you're unit testing third party stuff, then your build will fail as soon as those things are unavailable which might be a problem in the long run.
几年后,我做了更多的单元测试,感觉我更好地理解了这一点。单元测试擅长验证一段代码是否正确,假设您正确理解如何使用伪造(模拟/存根)的 API。但要正确伪造这些 API,您必须首先了解它们的工作原理。因此,在阅读了这些 API 的文档后,您可以通过进行概念验证(即使这意味着在编写代码后手动测试代码)或通过编写集成测试来检查您的理解。一旦您对第三方 API 有了一定的了解,您就可以在单元测试中伪造它并再次遵循 TDD。
第三方 API 的包装器非常适合编写集成测试,您只需测试最小的包装器,而无需伪造第三方 API,以确保您正确理解它。其中一些测试可能不是真正的测试,而是像测试一样编写的演示。它们稍后也会派上用场,因为如果您忘记某些内容是如何工作的,您可以查看它们,帮助同事理解 API,并在升级 API 时发现细微的重大更改。
今天,我经常编写包装器的集成测试,编写与我的情况相关的第三方 API 的演示/示例,甚至编写生产代码并手动测试它(如果需要)。只有当我使用的 API 存在歧义或不清楚时,我才需要这样做。一旦我对如何使用它充满信心,就该进行“正常”TDD 了。
A few years later, I have done much more unit testing, and feel I understand this better. Unit tests are good at verifying that a piece of code is correct ASSUMING that you correctly understand how to use the API's that are faked (mocked / stubbed). But to fake out those API's correctly, you must first understand how they work. So after reading the documentation for those API's, you can check your understanding by doing a proof-of-concept--even if that means testing code manually after writing it--or by writing an integration test. Once you are semi-comfortable with your understanding of the thrid-party API, you can fake it in a unit test and follow TDD once again.
Wrappers for third-party API's are an excellent thing to write integration tests for, where you merely test your minimal wrapper without faking the third-party API to ensure you correctly understand it. Some of these tests might not really be tests, but demonstrations written like tests. They come in handy later, too, because you can review them if you forget how something works, help a coworker understand the API, and discover subtle breaking changes when you upgrade the API.
Today, I often write integration tests of wrappers, write demonstrations / examples of third-party API's exercising corner cases relevant to my situation, and even write production code and manually test it if I have to. I only have to when there is an ambiguity or unclarity in the API I'm using. Once I feel confident about how to use it, it's time for "normal" TDD.