You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

多模块项目中配置Pitest关联Cucumber测试的技术问题

问题描述

项目结构

project/
├── module-with-java-code/
│   ├── main
│   ├── test
│   └── build.gradle
├── module-with-cucumber-features/
│   ├── features [test]/
│   │   ├── feature-test-folder-1/
│   │   │   ├── test-1.feature
│   │   │   └── ...
│   │   └── ...
│   ├── test/
│   │   ├── glue/
│   │   │   └── ...
│   │   ├── TestNgCucumberTest for feature-test-folder-1
│   │   └── ...
│   └── build.gradle
├── ...更多模块...
└── build.gradle

需求

对module-with-java-code模块执行Pitest变异测试,同时使用该模块自身的单元测试和module-with-cucumber-features模块中的Cucumber测试用例。

使用版本

  • gradle: 8.11.1
  • pitest-gradle-plugin: info.solidsoft.pitest:1.15.0
  • pitest-testng-plugin: org.pitest:pitest-testng-plugin:1.0.0
  • pitest-junit5-plugin: org.pitest:pitest-junit5-plugin:1.2.1
  • Cucumber依赖:
    • io.cucumber:cucumber-jvm-deps:1.0.6
    • io.cucumber:cucumber-picocontainer:7.20.1
    • io.cucumber:cucumber-java:7.20.1
    • io.cucumber:cucumber-testng:7.20.1
    • me.jvt.cucumber:reporting-plugin:7.11.0

遇到的问题

问题1:在module-with-cucumber-features模块配置时,报错No mutations found

配置代码:

configure(project(':module-with-cucumber-features')) {
    apply plugin: 'info.solidsoft.pitest'
    dependencies {
        implementation project(':module-with-java-code')
    }

    configurations { mutableCodeBase { transitive false } }
    dependencies { mutableCodeBase project(':module-with-java-code') }
    pitest {
        mutators = ["ALL"]
        mainSourceSets = [project(':module-with-java-code').sourceSets.main]
        testSourceSets = [sourceSets.test]
        targetTests = ['com.example.TestNgCucumberTest']
        additionalMutableCodePaths = [configurations.mutableCodeBase.singleFile]
    }
}

问题2:在根项目配置时,报错Could not get unknown property 'implementation' for configuration container for project ':module-with-java-code'

配置代码:

configure(project(':module-with-cucumber-features')) {
    apply plugin: 'info.solidsoft.pitest'
    apply plugin: 'java'

    dependencies {
        implementation project(':module-with-java-code')
    }

    //Additional configuration to resolve :module-with-java-code project JAR as mutable code path for PIT
    configurations {
        mutableCodeBase { transitive false }
        dependencies {
            mutableCodeBase.extendsFrom(project(':module-with-java-code').configurations.implementation)
        }
    }
    pitest {
        timestampedReports = false
        mainSourceSets = [project.sourceSets.main, project(':module-with-java-code').sourceSets.main]
        //Generates deprecation warning in Gradle 5.6+
        additionalMutableCodePaths = configurations.mutableCodeBase.files
//        additionalMutableCodePaths = project(':module-with-java-code').jar.outputs.files.getFiles()  //Workaround
    }
}

解决方案

正确的做法是在module-with-java-code模块中配置Pitest,同时引入Cucumber模块的测试代码作为额外测试源,避免反向配置带来的路径和依赖问题。

步骤1:配置module-with-java-code的build.gradle

plugins {
    id 'java'
    id 'info.solidsoft.pitest'
}

dependencies {
    // 保留自身单元测试的依赖(如JUnit/TestNG)
    testImplementation ... 
    // 引入Cucumber模块的测试代码与资源
    testImplementation project(':module-with-cucumber-features')
    // 配置Pitest所需的测试框架插件
    pitest 'org.pitest:pitest-testng-plugin:1.0.0'
    pitest 'org.pitest:pitest-junit5-plugin:1.2.1'
}

pitest {
    // 指定要变异的目标源码(当前模块的业务代码)
    mainSourceSets = [sourceSets.main]
    // 同时加载自身测试和Cucumber模块的测试代码
    testSourceSets = [sourceSets.test, project(':module-with-cucumber-features').sourceSets.test]
    // 指定要运行的测试类:自身单元测试 + Cucumber的TestNG运行器
    targetTests = ['com.yourpackage.*Test', 'com.example.TestNgCucumberTest']
    mutators = ["ALL"]
    timestampedReports = false
    // 确保Cucumber的feature文件能被加载到测试类路径
    additionalTestClasspath = project(':module-with-cucumber-features').sourceSets.test.resources.srcDirs
}

步骤2:调整module-with-cucumber-features的build.gradle

确保测试资源(.feature文件)能被其他模块访问:

plugins {
    id 'java'
}

sourceSets {
    test {
        resources {
            srcDir 'features' // 对应项目中的features目录
        }
    }
}

dependencies {
    implementation project(':module-with-java-code')
    // 保留原有的Cucumber依赖配置
    testImplementation 'io.cucumber:cucumber-java:7.20.1'
    testImplementation 'io.cucumber:cucumber-testng:7.20.1'
    testImplementation 'io.cucumber:cucumber-picocontainer:7.20.1'
    testImplementation 'io.cucumber:cucumber-jvm-deps:1.0.6'
    testImplementation 'me.jvt.cucumber:reporting-plugin:7.11.0'
}

步骤3:执行Pitest任务

在项目根目录运行以下命令:

./gradlew :module-with-java-code:pitest

问题原因分析

  1. 问题1(No mutations found):在Cucumber模块配置时,additionalMutableCodePaths指向的是打包后的JAR文件,而Pitest需要直接访问未打包的编译类文件。通过mainSourceSets指定目标源码才是正确的方式。
  2. 问题2(unknown property 'implementation'):project(':module-with-java-code').configurations.implementation写法错误,Gradle中不能直接通过配置容器访问implementation配置。直接在目标模块配置Pitest可完全避免这种复杂的跨模块依赖引用。

内容的提问来源于stack exchange,提问作者Daniël Gerritsen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 14:22:31