为什么单元测试应与集成测试分开运行
单元测试级别的TDD相当简单,因为单元测试中的类要么没有复杂的依赖关系,要么使用模拟框架(例如Mockito)来模拟依赖关系。 但是,当我们进入集成测试时,TDDSwift变得困难。 集成测试基本上是在测试具有部分或全部依赖关系的组件,而不是完全模拟它们。 示例包括跨多个层的测试,读取或写入数据库或文件系统的测试,需要启动Servlet容器或EJB容器的测试,涉及网络通信,Web服务的测试等。
集成测试往往比较脆弱和/或缓慢 。 例子:
- 与数据库对话的测试可能不会失败,不是因为代码中的逻辑错误,而是因为数据库已关闭,数据库的URL /用户名/密码已更改,或者数据库中的数据有误。
- 读取或写入磁盘的测试很慢,并且每次运行测试时,都需要使用正确的数据或内容来重置文件或数据库。
- 打包和部署到容器很慢。
- 进行网络调用的测试失败可能不是因为代码中的逻辑错误,而是因为网络资源不可用,或者网络本身存在问题。
这些麻烦往往会阻止开发人员频繁运行测试。 当测试运行的次数很少时,开发人员最终会在捕获错误之前编写大量代码。 因此,当不经常运行测试时,生产力下降,因为编写大量代码后更难发现和修复错误,并且存在质量问题的风险增加。 同样,当运行测试很麻烦时,不鼓励开发人员编写足够的测试。
因此,将单元测试与集成测试分开运行是有意义的。 单元测试完全在内存中运行,没有任何外部依赖关系,因此,即使对于大型项目,它们也都应该在短短几秒钟内运行,并且每次都应可靠运行,因为它们仅取决于被测代码的逻辑。 因此,鼓励开发人员进行每一个小的更改就可以运行所有单元测试。
使用Maven故障保护和JUnit @Category进行集成测试
分离集成测试的方法不止一种。 默认情况下,故障保护会选择后缀为“ IT”或“ ITCase”或以“ IT”为前缀的任何类。 但是,某些测试框架也需要后缀或前缀,这使得使用该方法很麻烦。 另一种方法是将集成测试放在单独的源目录中。 我选择使用JUnit @Category,因为我还使用了Concordion,它的测试类中需要一个后缀。
本文的其余部分仅记录了我如何实施John Doble在2012年发表的名为“使用Maven和JUnit类别进行单元和集成测试”的建议 。 您可以在这里找到我的源代码 。
创建JUnit类别
创建一个JUnit类别只是简单地创建一个空接口。 真的,就是这样! 见下文:
package com.orangeandbronze.test;public interface IntegrationTest {}
现在,我可以将此“标记接口”作为类别应用于我的集成测试-在下面的示例中,应用于SectionDaoTest。
import org.junit.experimental.categories.Category;
import com.orangeandbronze.test.IntegrationTest;@Category(IntegrationTest.class)
public class SectionDaoTest extends DaoTest {...
}
添加Surefire和故障安全插件
现在添加Surefire和Failsafe插件。 我需要排除Surefire(运行单元测试)中IntegrationTest标记的所有测试,并在Failsafe(运行集成测试)中包括IntegrationTest标记的所有测试。 另外,我必须包含“ ** / *。java”,否则测试将无法运行,我也不知道为什么。
<plugin><artifactId>maven-surefire-plugin</artifactId><version>2.18.1</version><configuration><excludedGroups>com.orangeandbronze.test.IntegrationTest</excludedGroups></configuration>
</plugin>
<plugin><artifactId>maven-failsafe-plugin</artifactId><version>2.18.1</version><configuration><includes><include>**/*.java</include></includes><groups>com.orangeandbronze.test.IntegrationTest</groups></configuration><executions><execution><goals><goal>integration-test</goal><goal>verify</goal></goals></execution></executions>
</plugin>
运行测试
所以现在,当我运行mvn test时,仅运行单元测试,而当我运行mvn Integration-test或mvn verify (通常运行mvn verify)时,不仅会运行单元测试,而且我的项目也会打包,然后集成测试运行。
在一个真实的项目中,每个开发人员只需进行几次更改即可运行所有的单元测试,一天要进行数十次,而他将不那么频繁地运行集成测试,但每天至少要运行一次。 CI服务器还将在其构建期间运行单元测试和集成测试。
翻译自: https://www.javacodegeeks.com/2015/01/separating-integration-tests-from-unit-tests-using-maven-failsafe-junit-category.html