[英]Integration tests, unit tests and code coverage
我正在为一位同事审查一些代码,并在单元测试类中遇到了一个测试,它看起来像这样:
// 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(...)
很明显,这是一个集成测试,因为它正在测试FooToBarConverter以及被测系统,因为它是唯一涵盖DoSomething()方法的测试。 我建议将此测试移至集成测试解决方案,但这会降低单元测试的代码覆盖率。 我们的目标是100%的单元测试代码覆盖率(是的 - 我知道100%的覆盖率是达到目的的手段而非终端本身,100%覆盖的代码不一定是100%正确的代码)。
如果我们将集成测试移出去,是否有理由创建单元测试以恢复覆盖范围?
或者我们是否针对100%单元测试覆盖率的错误做法? 我们是否应该通过组合所有测试(甚至100%的目标)来实现100%的覆盖率?
谢谢。
编辑/ UPDATE:
这不是关于如何正确地测试被测系统的问题(我知道这不是单元测试的原因,我知道如何正确地将其转换为单元测试),也不是关于覆盖范围的问题FooToBarConverter。 我希望对被测系统的代码覆盖率有所了解:对被测系统的集成测试是否足够? 还是应该进行单元测试?
我认为这里的答案是“它取决于”。
如果你在FooToBarConverter
类上有完整的单元测试覆盖率,那么你可能只需要使用systemUnderTest
的集成测试,因为你可以放心地说真正的FooToBarConverter
在这种情况下表现得如预期,因此不会错误地影响测试结果。
在另一方面,目前还不清楚具体是什么,这个测试是检查-你检查的行为systemUnderTest
给予有效时FooToBarConverter
,或在一些其他预期的副作用systemUnderTest
到FooToBarConverter
是纯属巧合演员? (即你确定这不是对bar
的间接测试吗?)
现在,我个人建议你也做了适当的,“纯”单元测试(使用模拟或存根FooToBarConverter
的) systemUnderTest
因为
它会使回归更容易管理; 假设将来对FooToBarConverter
某些更改会使其单元测试失败 - 因此很可能也会使此集成测试失败。 对于那些查看失败测试并且不知道可以忽略集成测试失败并且只需要修复FooToBarConverter测试的人来说,这可能会令人困惑。 我知道这是一件小事,但有一天可能会节省5分钟:)
如何测试负面情况(当给出一个破坏/无效/ null FooToBarConverter
时, systemUnderTest
行为)? 既然你可能不得不为这种情况编写带有存根/模拟的单元测试,你也可以在同一个项目/测试类中对好的情况进行单元测试,它更清晰 - 否则你有聚合单元测试和集成测试项目的代码覆盖率,以验证systemUnderTest
是否完全覆盖...
此外,不要担心100%的代码覆盖率; 这很好,但在实践中很少见到它。 我并不是说这对于良好的设计实践来说也是如此; 简单的现实是,没有任何设计是100%完美的,因此可以预期有时候你没有时间/资源/意愿来重构你的类以允许每个单独的依赖注入,或者是能够为每个缝间交互等使用接口
希望有所帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.