如何在Gradle中分离集成测试与单元测试
如何在Gradle中分离集成测试与单元测试
嘿,这个问题我熟!从Maven转Gradle想保留单元测试和集成测试的阶段分离完全没问题,咱们照着你之前的Maven逻辑来配置就行,Gradle灵活性很强,具体步骤如下:
首先,Gradle默认只有test这个测试源集,咱们得给集成测试单独建一个integrationTest源集,用来存放你的*IT.java测试类和相关资源。然后配置对应的测试任务,把它绑定到check任务(也就是你说的和Maven verify等价的任务)上就行。
第一步:配置集成测试源集
在你的build.gradle(Groovy DSL)里添加以下配置,用来定义集成测试的代码目录和类路径:
sourceSets { integrationTest { java { // 让集成测试能访问主代码和单元测试的代码/输出 compileClasspath += main.output + test.output runtimeClasspath += main.output + test.output // 指定集成测试的Java代码目录 srcDir file('src/integrationTest/java') } // 指定集成测试的资源文件目录 resources.srcDir file('src/integrationTest/resources') } }
第二步:配置集成测试依赖
集成测试通常需要和单元测试一样的依赖(比如JUnit 5),直接复用或者单独声明都可以,这里我直接复用单元测试的依赖配置:
dependencies { // 单元测试的JUnit 5依赖 testImplementation 'org.junit.jupiter:junit-jupiter-api:5.9.2' testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.9.2' // 集成测试的依赖,和单元测试保持一致 integrationTestImplementation sourceSets.test.output integrationTestImplementation 'org.junit.jupiter:junit-jupiter-api:5.9.2' integrationTestRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.9.2' }
第三步:创建集成测试任务并绑定到check阶段
接下来创建一个专门的integrationTest任务,指定只运行*IT.java结尾的测试类,并且让check任务依赖它——这样运行check的时候就会先跑单元测试,再跑集成测试,和Maven的verify阶段逻辑完全一致:
task integrationTest(type: Test) { description = 'Runs integration tests.' group = 'Verification' // 把任务归到Verification组,和check同组 // 指定测试类目录和类路径 testClassesDirs = sourceSets.integrationTest.output.classesDirs classpath = sourceSets.integrationTest.runtimeClasspath // 只筛选以IT结尾的测试类,和你之前的规则一致 include '**/*IT.java' // 把集成测试的报告和单元测试分开,方便后续查看 reports.html.outputLocation = file("${buildDir}/reports/integrationTests") reports.junitXml.outputLocation = file("${buildDir}/test-results/integrationTests") // 让check任务依赖这个集成测试任务 check.dependsOn integrationTest }
效果验证
配置完之后:
- 运行
./gradlew test:只会执行你的*Test.java单元测试,对应Maven的test阶段 - 运行
./gradlew check:会先执行test任务(单元测试),再执行integrationTest任务(集成测试),完全等价于Maven的verify阶段
如果你用的是Kotlin DSL(build.gradle.kts),对应的配置代码如下:
sourceSets { create("integrationTest") { java { compileClasspath += sourceSets.main.get().output + sourceSets.test.get().output runtimeClasspath += sourceSets.main.get().output + sourceSets.test.get().output srcDir("src/integrationTest/java") } resources.srcDir("src/integrationTest/resources") } } dependencies { testImplementation("org.junit.jupiter:junit-jupiter-api:5.9.2") testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.9.2") val integrationTestImplementation by configurations integrationTestImplementation(sourceSets.test.get().output) integrationTestImplementation("org.junit.jupiter:junit-jupiter-api:5.9.2") integrationTestRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.9.2") } tasks.register<Test>("integrationTest") { description = "Runs integration tests." group = "Verification" testClassesDirs = sourceSets["integrationTest"].output.classesDirs classpath = sourceSets["integrationTest"].runtimeClasspath include("**/*IT.java") reports.html.outputLocation = file("${buildDir}/reports/integrationTests") reports.junitXml.outputLocation = file("${buildDir}/test-results/integrationTests") tasks.check.get().dependsOn(this) }
备注:内容来源于stack exchange,提问作者Fábio
相关产品推荐
相关产品推荐

