该插件提供了执行突变测试并计算带有PIT的基于Gradle项目的突变覆盖范围的能力。
将gradle-pitest-plugin添加到build.gradle文件中的plugins配置:
plugins {
id ' java ' // or 'java-library' - depending on your needs
id ' info.solidsoft.pitest ' version ' 1.15.0 '
}plugins {
id( " java " ) // or "java-library" - depending on your needs
id( " info.solidsoft.pitest " ) version " 1.15.0 "
}使用Pitest任务致电Gradle:
gradle pitest
在测量结果之后,PIT创建的报告将放在${PROJECT_DIR}/build/reports/pitest目录中。
可选地使其取决于构建:
build . dependsOn ' pitest 'tasks.build {
dependsOn( " pitest " )
}请注意,在使pitest取决于另一个任务时,必须按名称提及。否则,Gradle将解决pitest到配置而不是任务。
“ plugins方式”有一些限制。由于插件的主要存储库是中央存储库(又名Maven Central),因此也可以使用“通用方式”将插件添加到您的项目中:
buildscript {
repositories {
mavenCentral()
// Needed only for SNAPSHOT versions
// maven { url 'https://oss.sonatype.org/content/repositories/snapshots/' }
}
dependencies {
classpath ' info.solidsoft.gradle.pitest:gradle-pitest-plugin:1.15.0 '
}
}buildscript {
repositories {
mavenCentral()
// Needed only for SNAPSHOT versions
// maven {
// url = uri("https://oss.sonatype.org/content/repositories/snapshots/")
// }
}
dependencies {
classpath( " info.solidsoft.gradle.pitest:gradle-pitest-plugin:1.15.0 " )
}
}应用插件:
apply plugin : ' java ' // or 'java-library' - depending on your needs
apply plugin : ' info.solidsoft.pitest ' apply (plugin = " java " ) // or "java-library" - depending on your needs
apply (plugin = " info.solidsoft.pitest " )如果您使用Junit 4,则不需要额外配置Pitest插件。在pitest Block中进行自定义:
pitest {
targetClasses = [ ' our.base.package.* ' ] // by default "${project.group}.*"
pitestVersion = ' 1.15.0 ' // not needed when a default PIT version should be used
threads = 4
outputFormats = [ ' XML ' , ' HTML ' ]
timestampedReports = false
}惯用和更便携的配置:
pitest {
targetClasses.set( setOf ( " our.base.package.* " )) // by default "${project.group}.*"
pitestVersion.set( " 1.15.0 " ) // not needed when a default PIT version should be used
threads.set( 4 )
outputFormats.set( setOf ( " XML " , " HTML " ))
timestampedReports.set( false )
}从Gradle 8.1开始,简单属性分配可用于配置插件(而不是set()方法):
pitest {
targetClasses = setOf ( " our.base.package.* " ) // by default "${project.group}.*"
pitestVersion = " 1.15.0 " // not needed when a default PIT version should be used
threads = 4
outputFormats = setOf ( " XML " , " HTML " )
timestampedReports = false
} Gradle中的配置是真正的Groovy代码,使所有作业都非常直观。 PIT期望的所有值应作为相应类型传递。只有一个重要区别。对于PIT期望在Gradle配置中昏迷的字符串列表的参数,应使用字符串列表(请参见上面示例中的outputFormats )。
检查PIT文档中的所有可用命令行参数的列表。插件配置中的预期参数格式可以从PitestPluginextension中获取。
为了使生活更容易taskClasspath ,该插件会自动设置mutableCodePaths , sourceDirs , reportDir ,详细信息, verbosity和pitestVersion 。此外,用户可以覆盖sourceDirs reportDir , verbosity和pitestVersion 。
Gradle插件有一些特定的参数:
testSourceSets定义测试源集应由PIT使用的测试源集(默认情况下sourcesets.test,但允许添加位于不同源集中的集成测试)mainSourceSets定义了PIT应该使用的主要源集(默认来源)mainProcessJvmArgs -JVM参数在启动主坑进程时将使用;请注意,PIT本身会启动另一个Java进程以进行突变测试执行,通常应使用jvmArgs来增加最大的内存大小(请参阅#7);additionalMutableCodePaths突变的其他类(对于与不同模块中的生产代码集成测试有用 - 请参见#25)useClasspathFile启用其他类Path作为文件内容(对具有很多类Path元素的Windows用户有用,默认为禁用)fileExtensionsToFilter提供了从Pit Class Path过滤其他文件扩展的能力(请参阅#53)例如:
pitest {
.. .
testSourceSets = [sourceSets . test, sourceSets . integrationTest]
mainSourceSets = [sourceSets . main, sourceSets . additionalMain]
jvmArgs = [ ' -Xmx1024m ' ]
useClasspathFile = true // useful with bigger projects on Windows
fileExtensionsToFilter . addAll( ' xml ' , ' orbit ' )
}pitest {
.. .
testSourceSets.set( listOf (sourceSets.test.get(), sourceSets.getByName( " integrationTest " )))
mainSourceSets.set( listOf (sourceSets.main.get(), sourceSets.getByName( " additionalMain " )))
jvmArgs.set( listOf ( " -Xmx1024m " ))
useClasspathFile.set( true ) // useful with bigger projects on Windows
fileExtensionsToFilter.addAll( " xml " , " orbit " )
}PIT在JVM中执行测试,独立于Gradle用来执行测试的JVM。如果您的测试需要某些系统属性,则必须将它们传递给PIT,因为该插件不会为您服务:
test {
systemProperty ' spring.test.constructor.autowire.mode ' , ' all '
}
pitest {
jvmArgs = [ ' -Dspring.test.constructor.autowire.mode=all ' ]
}tasks.test {
systemProperty( " spring.test.constructor.autowire.mode " , " all " )
}
pitest {
jvmArgs.set( listOf ( " -Dspring.test.constructor.autowire.mode=all " ))
}如#170 Intellij Idea所报道,显示了有关在build.gradle中设置最终字段(懒惰配置)的警告。这不是一个真正的问题,因为Gradle在内部拦截了这些呼叫并使用设置器。然而,以较少可读代码为代价的人更喜欢没有(少)警告的人可以使用二传手,例如:
testSourceSets . set([sourceSets . test, sourceSets . integrationTest])
mainSourceSets . set([sourceSets . main, sourceSets . additionalMain])
jvmArgs . set([ ' -Xmx1024m ' ])
useClasspathFile . set( true ) // useful with bigger projects on Windows
fileExtensionsToFilter . addAll( ' xml ' , ' orbit ' )Gradle-Pitest-Plugin可用于多模块项目。 Gradle-pitest-Plugin依赖项应添加到根项目中的构建单词配置中,而插件必须在所有子标记中应用于应使用PIT处理的所有子标记。来自build.gradle的样本片段,位于根项目:
// in root project configuration
plugins {
id ' info.solidsoft.pitest ' version ' 1.15.0 ' apply false
}
subprojects {
apply plugin : ' java '
apply plugin : ' info.solidsoft.pitest '
pitest {
threads = 4
if (project . name in [ ' module-without-any-test ' ]) {
failWhenNoMutations = false
}
}
} // in root project configuration
plugins {
id( " info.solidsoft.pitest " ) version " 1.15.0 "
}
subprojects {
apply (plugin = " java " )
apply (plugin = " info.solidsoft.pitest " )
pitest {
threads.set( 4 )
if (project.name in setOf ( " module-without-any-test " )) {
failWhenNoMutations.set( false )
}
}
}可以使用插件info.solidsoft.pitest.aggregator和Task pitestReportAggregate来汇总多模块项目的Pitest报告。 Root Project必须适当配置以使用pitestReportAggregate :
// in root project configuration
plugins {
id ' info.solidsoft.pitest ' version ' 1.15.0 ' apply false
}
apply plugin : ' info.solidsoft.pitest.aggregator ' // to 'pitestReportAggregate' appear
subprojects {
apply plugin : ' java '
apply plugin : ' info.solidsoft.pitest '
pitest {
// export mutations.xml and line coverage for aggregation
outputFormats = [ " XML " ]
exportLineCoverage = true
timestampedReports = false
.. .
reportAggregator { // since 1.9.11 - extra results validation, if needed
testStrengthThreshold . set( 50 ) // simpler Groovy syntax (testStrengthThreshold = 50) does not seem to be supported for nested properties
mutationThreshold . set( 40 )
maxSurviving . set( 3 )
}
}
} // in root project configuration
plugins {
id( " info.solidsoft.pitest " ) version " 1.15.0 "
}
apply (plugin = " info.solidsoft.pitest.aggregator " )
subprojects {
apply (plugin = " java " )
apply (plugin = " info.solidsoft.pitest " )
pitest {
outputFormats.set( setOf ( " XML " ))
timestampedReports.set( false )
exportLineCoverage.set( true )
.. .
reportAggregator {
testStrengthThreshold.set( 50 )
mutationThreshold.set( 40 )
maxSurviving.set( 3 )
}
}
}在执行pitest pitestReportAggregate任务之后,汇总报告将放置在${PROJECT_DIR}/build/reports/pitest Directory中。
可以突变位于不同子弹中的代码。 Gradle在内部不依赖其他子标记的输出目录,而是构建JAR并使用其中的类。对于坑,这些是两组不同的类文件集,因此为了使其起作用,要定义mainSourceSets和additionalMutableCodePaths 。例如:
configure(project( ' :itest ' )) {
apply plugin : ' info.solidsoft.pitest '
dependencies {
implementation project( ' :shared ' )
}
configurations { mutableCodeBase { transitive false } }
dependencies { mutableCodeBase project( ' :shared ' ) }
pitest {
mainSourceSets = [project . sourceSets . main, project( ' :shared ' ) . sourceSets . main]
additionalMutableCodePaths = [configurations . mutableCodeBase . singleFile]
}
}configure( listOf (project( " :itest " ))) {
apply (plugin = " info.solidsoft.pitest " )
dependencies {
implementation(project( " :shared " ))
}
val mutableCodeBase by configurations.creating { isTransitive = false }
dependencies { mutableCodeBase(project( " :shared " )) }
pitest {
mainSourceSets.set( listOf (project.sourceSets.main.get(), project( " :shared " ).sourceSets.main.get()))
additionalMutableCodePaths.set( listOf (mutableCodeBase.singleFile))
}
}以上是Gradle团队推荐的方式,但是在特定情况下,更简单的解决方案也应起作用:
configure(project( ' :itest ' )) {
apply plugin : ' info.solidsoft.pitest '
dependencies {
implementation project( ' :shared ' )
}
pitest {
mainSourceSets = [project . sourceSets . main, project( ' :shared ' ) . sourceSets . main]
additionalMutableCodePaths = project( ' :shared ' ) . jar . outputs . files . getFiles()
}
}configure( listOf (project( " :itest " ))) {
apply (plugin = " info.solidsoft.pitest " )
dependencies {
implementation(project( " :shared " ))
}
pitest {
mainSourceSets.set( listOf (project.sourceSets.main.get(), project( " :shared " ).sourceSets.main.get()))
additionalMutableCodePaths.set(project( " :shared " ).task( " jar " ).outputs.files)
}
}功能测试套件可用最少的工作多项目构建。
测试插件用于支持与Junit4相比的不同测试框架。
从此版本开始,将pit与Junit 5一起使用所需的配置已简化为以下内容:
plugins {
id ' java '
id ' info.solidsoft.pitest ' version ' 1.15.0 '
}
pitest {
// adds dependency to org.pitest:pitest-junit5-plugin and sets "testPlugin" to "junit5"
junit5PluginVersion = ' 1.0.0 ' // or 0.15 for PIT <1.9.0
// ...
}plugins {
id( " java " )
id( " info.solidsoft.pitest " ) version " 1.15.0 "
}
pitest {
// adds dependency to org.pitest:pitest-junit5-plugin and sets "testPlugin" to "junit5"
junit5PluginVersion.set( " 1.0.0 " )
}请注意。 PIT 1.9.0需要Pitest-Junit5-Plugin 1.0.0+。 Junit Jupiter 5.8(Junit Platform 1.8)需要Pitest-Junit5-Plugin 0.15+,而5.7(1.7)的要求为0.14。设置了项目中使用的junit 5版本的正确插件版本,以避免运行时错误(例如`nosuchmethoderror:'java.util.optional org.junit.junit.junit.platform.commons.util.annotitation.annotationutils.findannotils.findannotation(java.lang.class.class.class,java.lang.lang.lang.class,boolean))。
Junit 5的最小工作示例可在功能测试套件中提供。
对于将Junit 5与其他Pit插件混合在一起,您可以在我的博客文章中阅读此部分。
要启用PIT插件,足以将其添加到buildscript闭合中的Pitest配置中。例如:
plugins {
id ' java '
id ' info.solidsoft.pitest ' version ' 1.15.0 '
}
repositories {
mavenCentral()
}
dependencies {
pitest ' org.example.pit.plugins:pitest-custom-plugin:0.42 '
}plugins {
id( " java " )
id( " info.solidsoft.pitest " ) version " 1.15.0 "
}
repositories {
mavenCentral()
}
dependencies {
pitest( " org.example.pit.plugins:pitest-custom-plugin:0.42 " )
}最小的工作示例可在功能测试套件中获得。
请注意。在Gradle-pitest-Plugin <1.5.0中,必须在root Project的buildscript范围中创建pitest配置。请注意。从PIT 1.6.7开始,不再需要设置testPlugin配置参数。它在Gradle插件中也被弃用。
默认情况下,每个Gradle-pitest-Plugin版本都使用预定义的坑版本。通常,这是发布插件版本时可用的最新发布版本。可以通过在pitest配置闭合中使用pitestVersion参数来覆盖它。
请注意,在某些情况下,使用非默认坑版本时可能存在一些问题。
如果没有另行说明,Gradle-pitest-Plugin 1.9.x默认使用PIT 1.9.x,1.7.x使用PIT 1.7.X等。最小支持的PIT版本为1.7.1。
从1.7.0版Gradle-Pitest-Plugin开始,需要Gradle 6.4。 Gradle 5.X(5.6+)支持的最新版本为1.6.0。在Java 11下,使用Gradle 6.4、6.9.1和7.4.2自动测试了当前版本。使用Java 11+的测试仅限于Gradle和Pit的兼容版本。
可以用1.7.0+测试Java 17的实验支持。
从版本1.3.0开始生产的二进制文件需要Java 8(作为用于运行Gradle构建的JDK)。但是,拥有Java 17 LTS于2021年9月发布,从Gradle-Pitest-Plugin 1.9.0开始,对JDK <11的支持已被弃用(请参阅#299)。
有关插件本身更改的更详细列表,请参见ChangElog文件。
Gradle不提供通过命令行覆盖插件配置的内置方法,但是可以使用Gradle-oferride-Plugin来做到这一点。
在您的项目中应用了gradle-oferride-plugin后,可以按照以下操作:
./gradlew pitest -Doverride.pitest.reportDir=build/pitReport -Doverride.pitest.threads=8
笔记。该机制应适用于字符串和数字属性,但在支持列表/集合/地图和布尔值的情况下存在局限性。
有关更多信息,请参见项目网页。
默认情况下,Gradle-Pitest-Plugin使用相应的坑版本(具有相同的数字)。插件仅在发生内部更改或需要适应新的PIT版本的更改时才会发布该插件。有一种专门的机制可以允许使用最新的PIT版本(例如,BugFix发行版)或在发生发现的问题的情况下降级坑。要覆盖默认版本,足以在pitest配置闭合中设置pitestVersion属性。
pitest {
pitestVersion = ' 2.8.1-the.greatest.one '
}pitest {
pitestVersion.set( " 2.8.1-the.greatest.one " )
}如果检测到插件的最新版本与较新的坑版本一起检测到的错误,请提出问题。
可以将PIT报告直接放入${PROJECT_DIR}/build/reports/pitest可以使用timestampedReports配置属性启用:
pitest {
timestampedReports = false
}pitest {
timestampedReports.set( false )
}有时,调试Gradle-Pitest-Plugin执行或PIT执行本身(例如PIT中的NPE)以提供明智的错误报告可能很有用。
可以通过添加-Dorg.gradle.debug=true到命令行,可以远程调试gradle-pitest-plugin执行。
但是,由于PIT是作为一个单独的过程来调试其执行的一个单独的过程,因此需要将以下参数添加到插件配置中:
pitest {
mainProcessJvmArgs = [ ' -agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5005 ' ]
}pitest {
mainProcessJvmArgs.set( listOf ( " -agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5005 " ))
}简短的答案是:不是直接。由于“标准” Java应用程序与Gradle中的Android Java应用程序之间的某些不兼容,该插件不支持以后。幸运的是,Karolwrótniak维护的插件的Android叉子提供了支持Android应用程序的修改版本(但另一方面,它与标准Java应用程序不起作用)。
Gradle-pitest插件1.5.0最终放松了(位置) pitest配置的方式(#62),这也在Gradle 6+中生成折旧警告。此更改不是向后兼容的,因此必须进行手动迁移 - 请参阅发行说明。这仅使用外部自定义插件影响项目。
重要的。由于PIT的Junit 5插件绝对是最受欢迎的,从1.4.7开始,有一种简化的方法如何使用junit5PluginVersion进行配置(绝对建议使用)。请参阅我的博客文章以了解如何迁移(它也解决了1.5.0+的兼容性问题)。
verbosity选项) 可以使用gradle命令构建从存储库克隆的gradle-pitest-plugin:
./gradlew build
在另一个项目中可见的带有本地更改的罐子的最简单方法是将其安装到本地Maven存储库中:
./gradlew install
也有使用星云测试编写的基本功能测试,可以运行:
./gradlew funcTest
MarcinZajączkowski在贡献者的帮助下,Gradle-Pitest-Plugin是由MarcinZajączkowski撰写的。可以直接通过电子邮件与作者联系:MSZPAK ATT WP DOTT PL。还有Marcin的博客可用:实心软 - 工作代码还不够。
该插件肯定具有一些错误和缺少功能。可以使用问题跟踪器进行报告。但是,首先将问题发送到Pit邮件列表通常是一个更好的主意。
该插件已根据Apache许可证的条款获得许可,版本2.0。