支持集成测试而不是单元测试是错误的吗?

时间:2012-07-24 10:49:40

标签: unit-testing mocking integration-testing

我们正在运行一个项目,在开发开始很久之后我们开始采用测试驱动设计。

我们有单元测试和集成测试。集成测试在真实数据库上运行,在运行测试之前以已知状态初始化。

在我们编写测试时,我们开始注意到,甚至对于那些可以在“标准方式”下进行测试的类,我们也是如此。使用模拟对象,它实际上变得更快,更清晰(阅读:更短和更容易理解代码),只使用直接与数据库交谈的真实对象/服务,而不是使用复杂的模拟对象设置混乱测试类。

这种方法有什么问题吗?

2 个答案:

答案 0 :(得分:2)

如果您使用的是真实对象/服务,那么您不知道测试失败的原因。例如。您在服务实现中更改了某些内容,或者重命名了数据库字段,或者您的网络已关闭 - 您有50个失败的“单元”测试。此外,在这种情况下,您无法进行测试驱动开发,因为在您编写测试之前,应该执行您正在测试的类所需的依赖项。您能预见到服务的消费者需要哪种API吗?这将导致可用的API和代码不太常用(参数,方法等)。

如果您的测试需要付出很多努力来安排模拟,那么:

  • 测试应简短而简单
  • 不验证已经验证的其他测试
  • 依赖项应该易于与
  • 交互
  • 尝试为您的课程(依赖性和sut)遵循单一责任原则
  • 尝试关注Tell Don't Ask Principle - 而不是要求许多问题依赖,告诉它你想要什么

答案 1 :(得分:1)

根本没有错。相反,根据我的经验,我会说支持单元测试是错误的。你的团队对测试感觉更快,更清洁"和我多年前以及从那时起的情况一样。

我甚至建议您完全放弃单元测试,并继续投资集成测试。我说这是一个用一个非常复杂的模拟API开发一个测试库的人,他多年来一直对孤立的单元测试提出疑问,然后最终得出结论集成测试(在编写了两种类型的测试之后)是所以更好。

但是,有一个更正:单元测试"隔离&用模拟对象" "标准方式"。您可能知道,Kent Beck是"father" of TDD和JUnit的发明者。但是猜猜看,肯特在他的TDD单元测试中根本没有使用模拟。严格来说,"单位"由发明TDD的人编写的测试更接近集成测试,因为他们不会将测试单元与其依赖关系隔离开来。 (这是关于单元测试的常见误解。有关准确的定义,请参阅Martin Fowler撰写的this article。)