集成测试的集成测试的依赖性:构建JUnit集成测试的一个好的/致命的不可实现的策略?

时间:2012-11-08 16:20:50

标签: java unit-testing junit integration-testing

我正在使用的系统(幸运的是)已经进行了JUnit单元测试,它覆盖了一定比例的代码功能(我认为总比没有好)。

系统中的方法高度依赖于彼此,并且可以作为输入发送到方法的参数的组合是巨大的。我们来看一个例子:

public void showMessage (final Language language, final Applications apps, final UserID userId)

根据不同的应用和userIds,上述方法可以弹出超过300,000个不同的消息框。除了是否至少对其中的几个方法施加如此巨大的压力之外,听起来是否可以解决(IMO在设计方面无法证明其合理性),我们遇到了可能导致巨大问题的恐惧。

话虽如此,我们发现的只是如下:

  1. 重构JUnit单元测试
  2. 在方法中提取很多对象作为参数
  3. 创建对象工厂
  4. 使用工厂创建的不同输入进行单元测试(可能是蛮力测试?)
  5. 检查新重构测试的结果
  6. 基本上,问题如下:

    在单元测试之上创建集成测试:可能性和挑战?这是一种定制方法还是一种合理的标准方法?将这些测试放在项目文件和项目构建生命周期的哪个位置,是否应该一直构建它们以完成构建过程?

    任何类型的反馈/评论,均来自JUnit实施限制和设计/创意限制。

2 个答案:

答案 0 :(得分:2)

集成测试的重点是验证组件是否正确地进行了交互。每个单元测试都应验证代码中的单个原子片。一般的经验法则(根据我的经验),如果你有一个单元测试超过10行代码你做错了什么,这当然排除了技术上属于@Before / {中的测试的一部分的代码{1}}阻止。关于单元测试的另一件事是,他们可以对其他任何集成测试具有 no 依赖性。我不会使用您上面描述的方法,因为单元测试是使用静态数据。这在回归测试中也发挥了重要作用,旧的单元测试进入了一个在发布之前执行的回归套件。

您的集成测试将依赖于诸如DBUnit,Selenium等项目。这需要依赖项,例如数据库或GUI来执行/验证。单元测试应该在开发人员执行签入之前运行。每次发生更改时都应该运行集成测试(或者对于潜在错误的容忍度,每天一次太少)。

我再次建议在单元测试中反对动态数据。主要是因为你的断言可能会失败,但它并不能证明单元测试是无效的。

<强>更新

  

嗯,是的,正如我所说,我认为这是一次集成测试。我是什么   我不确定是在集成测试中,你正在测试   系统链,而不是那些系统的单元测试!两者之间的依赖关系   单元测试和集成测试也是一个问题,IMO!

答复:
您对单元测试副集成测试存在根本性的误解。代码单元,即函数没有任何依赖关系,如果它们确实需要对您的架构进行严格的改造。通过集成测试,您必须构建不同的场景,以证明两个不相交的模块相互交互。这并不意味着将两个单元测试的逻辑组合成一个“集成”测试。

答案 1 :(得分:0)

阿米尔,

在单元测试之上构建“集成测试”是什么意思?我会看到集成测试是粗粒度的黑盒测试,测试部署在服务器上的应用程序与真正的数据库,JMS队列,第三方Web服务等进行交谈。通常,您可能想要模拟您不拥有的基础架构(如第三方网络服务等)。

集成测试将比单元测试慢得多,因此您不希望每次构建都执行它们。如果您使用像jenkins这样的CI服务器,您可以创建一个单独的集成构建,它将执行您拥有的所有测试(单元+集成)。

您在单元测试中提到了动态数据。 我认为使用静态输入数据进行单元测试以确保它们在每次执行时都覆盖相同的执行路径,验证在引入新代码时是否发生了任何行为更改或测试某些极端情况......

但..

使用随机输入数据来强调应用程序的附加测试套件也是一个好主意。 AFAIK Lucene / Solr的人采用了这种方法,他们甚至开源他们拥有随机测试的framerwork。看看这些链接:

http://labs.carrotsearch.com/randomizedtesting.html

http://vimeo.com/32087114

关于如何使用传统软件的一般方法,我推荐M. Feather的“有效使用遗留代码”。优秀的书籍,它可能会为您提供一些如何通过单元测试覆盖现有代码并提高代码质量的想法。

http://www.amazon.com/Working-Effectively-Legacy-Michael-Feathers/dp/0131177052