在我的办公室,除了对主要负责与文件系统(数据库等)交互的类进行集成测试外,我们还对单元测试的必要性存在争议。
我们拥有的集成测试几乎是单元测试,因为测试对象根本不与其他对象交互。我们称测试集成的唯一原因是测试中使用了真正的文件系统。并且建议让被测类使用文件系统层组件,然后在测试中模拟它(所以我们称之为单元测试),并检查与该组件的交互,而不是真实的文件系统结果。我们讨论的是这种改变的必要性。
我们的一个观点是,单元测试总是需要的,因为:
- 编写单元测试让代码变得更好
- 进行单元测试,您无需关心真实的文件系统和文件的副作用,出现在错误的位置
- 开发人员可以通过使测试的类使用文件系统模拟并为该模拟设置适当的期望来全面测试结果
- 可以将 mock 期望与被测类的特定内部算法联系起来,因为我们使用单元测试进行白盒测试
因此,必须始终为这样的测试类编写单元测试。并且该类必须始终使用文件系统层组件进行测试。
另一种观点是,专门用于文件系统交互的类的特定边缘情况不需要单元测试,因为:
- 仅仅通过简单的模拟而不是真实的文件系统(或其完整仿真),无法正确验证测试类是否有效。文件系统是一个如此复杂的组件,它:
- 一个经过测试的课程可以以多种不同的方式工作,以取得成功的结果。模拟期望仅涵盖一两种可能的场景,因此单元测试错误地显示正确实现良好算法的类的失败,这与预期不同。
- 一个经过测试的类可以以某种方式工作,被模拟检测为成功的场景,而该类仍然没有产生正确的结果。这可能是由于实际文件系统中相当复杂的原因。所有这些原因是不可能仅仅通过一个模拟来涵盖的。
- 带有模拟和期望的单元测试非常脆弱,因为它与被测类的内部算法密切相关。并且即使对算法进行正确的更改,测试也会错误地失败。
- 当类只有 1-2 个公共方法并且唯一的依赖项是文件系统时,集成测试是单元测试的适当且完全的替代品。集成测试在这种情况下提供与单元测试相同的好处 - 清晰的依赖关系,更易读的代码等。
因此,在我们的案例中不需要使用文件系统模拟进行单元测试。对于这种特殊的类情况,它很脆弱并且不准确。
所以,总而言之,问题是:
对于没有复杂类的边缘情况,集成测试是否足够充分,它主要负责使用文件系统(数据库等)?
此类的集成测试和单元测试之间的唯一区别在于,单元测试将使用文件系统模拟(类将完全隔离),而集成测试使用真实文件系统。
如果您可以添加对经典书籍的引用,或者可能是知名业内人士的文章/演示文稿,我将不胜感激,这样我们就可以有一个非常强大的基础来支持所得出的结论。