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