简体   繁体   English

集成测试,单元测试和代码覆盖

[英]Integration tests, unit tests and code coverage

I was reviewing some code for a colleague and came across a test in the unit test class that looked this: 我正在为一位同事审查一些代码,并在单元测试类中遇到了一个测试,它看起来像这样:

// setup
Foo f = ...
FooToBarConverter ftb = ...
Bar b = ftb.Convert(f); // It is easier to create a Bar by converting it from a Foo than making one 'from scratch'

// test
systemUnderTest.DoSomething(bar);

// assert
Assert.IsTrue(...)

Clearly this is an integration test as it is testing the FooToBarConverter as well as the system under test as it is the only test that covers the DoSomething() method. 很明显,这是一个集成测试,因为它正在测试FooToBarConverter以及被测系统,因为它是唯一涵盖DoSomething()方法的测试。 I suggested moving this test to an integration test solution, however this reduces the code coverage of the unit tests. 我建议将此测试移至集成测试解决方案,但这会降低单元测试的代码覆盖率。 We are aiming for 100% unit test code coverage (and yes - I know that 100% coverage is a means to an end not the end itself, and 100% covered code is not necessarily 100% correct code). 我们的目标是100%的单元测试代码覆盖率(是的 - 我知道100%的覆盖率是达到目的的手段而非终端本身,100%覆盖的代码不一定是100%正确的代码)。

Is there a reason for creating unit tests to bring the coverage back up if we move the integration test out? 如果我们将集成测试移出去,是否有理由创建单元测试以恢复覆盖范围?

Or are we aiming for the wrong thing with 100% unit test coverage? 或者我们是否针对100%单元测试覆盖率的错误做法? Should we be aiming for 100% coverage with the combination all our tests (or even aiming for 100% at all)? 我们是否应该通过组合所有测试(甚至100%的目标)来实现100%的覆盖率?

Thank you. 谢谢。

EDIT/UPDATE: 编辑/ UPDATE:

This is not a question about how to unit test the system under test properly (I know the reasons that this is not a unit test, and I know how to properly convert it into a unit test), nor is it a question on coverage on FooToBarConverter. 这不是关于如何正确地测试被测系统的问题(我知道这不是单元测试的原因,我知道如何正确地将其转换为单元测试),也不是关于覆盖范围的问题FooToBarConverter。 I want opinions on code coverage on the system under test: are integration tests on the system under test sufficient? 我希望对被测系统的代码覆盖率有所了解:对被测系统的集成测试是否足够? or should there also be unit tests? 还是应该进行单元测试?

I think the answer here is "it depends". 我认为这里的答案是“它取决于”。

  • If you have full unit test coverage on the FooToBarConverter class then probably you are OK just with the integration test of systemUnderTest because you can say with confidence that the real FooToBarConverter behaves as expected in this context and therefore does not incorrectly influence the result of the test. 如果你在FooToBarConverter类上有完整的单元测试覆盖率,那么你可能只需要使用systemUnderTest的集成测试,因为你可以放心地说真正的FooToBarConverter在这种情况下表现得如预期,因此不会错误地影响测试结果。

  • On the other hand, it's unclear specifically what this test is checking for - are you examining the behaviour of systemUnderTest when given a valid FooToBarConverter , or some other expected side effect within systemUnderTest to which FooToBarConverter is a purely coincidental actor? 在另一方面,目前还不清楚具体是什么,这个测试是检查-你检查的行为systemUnderTest给予有效时FooToBarConverter ,或在一些其他预期的副作用systemUnderTestFooToBarConverter是纯属巧合演员? (ie are you sure that this isn't an indirect test of bar ?) (即你确定这不是对bar的间接测试吗?)

Now personally I would recommend that you also do a proper, "pure" unit test (using a mock or stub of FooToBarConverter ) for systemUnderTest because 现在,我个人建议你也做了适当的,“纯”单元测试(使用模拟或存根FooToBarConverter的) systemUnderTest因为

  • it will make regressions easier to manage; 它会使回归更容易管理; suppose that in the future some change to FooToBarConverter makes its unit tests fail - they will quite possibly also therefore make this integration test fail. 假设将来对FooToBarConverter某些更改会使其单元测试失败 - 因此很可能也会使此集成测试失败。 That could be confusing for someone looking at failed tests and not knowing that the integration test failure can be ignored and that only the FooToBarConverter tests need to be fixed. 对于那些查看失败测试并且不知道可以忽略集成测试失败并且只需要修复FooToBarConverter测试的人来说,这可能会令人困惑。 It's a small thing, I know, but it might save 5 important minutes some day :) 我知道这是一件小事,但有一天可能会节省5分钟:)

  • How do you test the negative cases (behaviour of systemUnderTest when given a broken/invalid/null FooToBarConverter )? 如何测试负面情况(当给出一个破坏/无效/ null FooToBarConverter时, systemUnderTest行为)? Since you'll probably have to write unit tests with stubs/mocks for these kind of cases anyway, you might as well have a unit test for the good case in the same project/test class as well, it's much clearer - otherwise you have to aggregate code coverage across both unit test and integration test projects to verify that systemUnderTest is fully covered... 既然你可能不得不为这种情况编写带有存根/模拟的单元测试,你也可以在同一个项目/测试类中对好的情况进行单元测试,它更清晰 - 否则你有聚合单元测试和集成测试项目的代码覆盖率,以验证systemUnderTest是否完全覆盖...

Also, don't worry about 100% code coverage; 此外,不要担心100%的代码覆盖率; it's nice to have but in practice it's rare to see it. 这很好,但在实践中很少见到它。 I don't mean this as a sop to good design practices either; 我并不是说这对于良好的设计实践来说也是如此; the simple reality is that no design is 100% perfect and therefore it's to be expected that there are times when you just don't have the time/resource/will to refactor your classes to allow every single dependency to be injected, or to be able to use interfaces for every inter-seam interaction, etc. 简单的现实是,没有任何设计是100%完美的,因此可以预期有时候你没有时间/资源/意愿来重构你的类以允许每个单独的依赖注入,或者是能够为每个缝间交互等使用接口

Hope that helps. 希望有所帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM