可以选择在现有系统中添加单元测试或集成测试,哪个更好,为什么?

时间:2011-05-24 14:59:24

标签: java unit-testing junit

我目前正在咨询现有系统,我怀疑正确的下一步是添加单元测试,因为正在发生的异常类型(空指针,空列表,无效的返回数据)。但是,在应用程序中进行“个人投资”的员工坚持进行集成测试,即使报告的问题与特定用例失败无关。在这种情况下,最好从单元测试还是集成测试开始?

4 个答案:

答案 0 :(得分:4)

通常,很难对未经测试的代码库进行改造以进行单元测试。将会有高度的耦合,并且运行单元测试将比您获得的回报更大的时间下降。我推荐以下内容:

  • 至少获取Michael Feathers的Working Effectively With Legacy Code一份副本,并与团队成员一起完成。它涉及这个问题。
  • 对所有编写的新代码实施严格的单元测试(最好是TDD)策略。这将确保新代码不会成为遗留代码,并且获取要测试的新代码将推动旧代码的重构以实现可测试性。
  • 如果您有时间(您可能不会),请在系统的关键路径上编写一些关键的集成测试。这是一个很好的理智检查,你在步骤#2中进行的重构不会破坏核心功能。

答案 1 :(得分:2)

集成测试可以发挥重要作用,但测试代码的核心是单元测试。

一开始,您可能只会被迫进行集成测试。原因是你的代码库非常紧密耦合(只是一个疯狂的猜测,因为没有单元测试)。紧耦合意味着您无法在不首先创建大量相关对象的情况下创建对象的实例以进行测试。这使得每个定义的任何测试集成测试。编写这些集成测试至关重要,因为它应该用作您的错误查找/重构工作的基线。

  1. 编写记录错误的测试。

  2. 修复错误,使所有创建的单元测试都为绿色。

  3. 现在是时候成为一个好的boyscout了(让营地/代码以更好的顺序离开你进入时):编写测试,记录包含该bug的类的功能。

  4. 作为你们boyscout工作的一部分,你开始将课程与其他人分开。依赖注入是这里的工具。认为不应该在其他类中构造其他类 - 它们应该作为接口注入。

  5. 最后,当您将类解耦时,您也可以解耦测试。现在,当您注入接口而不是在测试类中创建具体实例时,您可以改为创建存根/模拟。突然,你的测试已成为单元测试!!

  6. 您也可以创建集成测试,在这里您可以注入具体类而不是存根和模拟。只要记住让它们远离单元测试;最好是在另一个组件中单元测试应该能够一直运行,并且运行速度非常快,不要让它们通过慢速集成测试减慢速度。

答案 2 :(得分:2)

问题的答案取决于提出问题的背景。如果您希望使用现有的代码库,并且考虑重写或替换大部分代码,那么围绕您希望重写或替换的组件设计一套全面的集成测试将更有价值。另一方面,如果您要对需要支持和维护的现有系统负责,您可能需要先从单元测试开始,以确保更集中的更改不会引入错误。

我会用另一种方式。如果有人送你一辆旧车,请看一下。如果您要立即更换所有组件,请不要费心测试燃油喷射器的微小性能特征。另一方面,如果您要维护汽车,请继续为您将要修理的组件编写有针对性的单元测试。

一般规则,没有单元测试的代码很脆弱,没有集成的系统很脆弱。如果您将专注于低级代码更改,请首先编写单元测试。如果您将专注于系统级更改,请编写集成测试。

此外,请务必忽略您在此类网站上阅读的所有内容。这里没有人知道你项目的具体细节。

答案 3 :(得分:1)

在集成测试和单元测试之间进行选择是非常主观的。它取决于代码库的各种指标,最显着的是内聚和类的耦合。

我将提供的通用建议是,如果松散耦合的类,那么测试设置将花费更少的时间,因此,开始编写单元测试会更容易(特别是对于更关键的类)代码库)。

另一方面,在高耦合的情况下,可能更好地针对更关键的代码路径编写集成测试,尤其是从松散耦合的类开始(并且驻留很多在执行堆栈中更高)。同时,必须尝试重构所涉及的类以减少耦合(同时使用集成测试作为安全网)。