El complemento proporciona la capacidad de realizar una prueba de mutación y calcular una cobertura de mutación de un proyectos basados en graduación con PIT.
Agregue Gradle-Pitest-Plugin a la configuración plugins en su archivo build.gradle :
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 "
}Llame a Gradle con la tarea de Pitest:
gradle pitest
Después de las medidas, un informe creado por PIT se colocará en ${PROJECT_DIR}/build/reports/pitest Directory.
Opcionalmente, haga que dependa de la compilación:
build . dependsOn ' pitest 'tasks.build {
dependsOn( " pitest " )
} Tenga en cuenta que al hacer que pitest dependa de otra tarea, debe referirse por su nombre. De lo contrario, Gradle resolverá pitest a la configuración y no a la tarea.
"The plugins Way" tiene algunas limitaciones. Como el repositorio principal para el complemento es el repositorio central (también conocido como Maven Central), también es posible agregar el complemento a su proyecto utilizando "La forma genérica":
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 " )
}
}Aplicar el complemento:
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 " ) El complemento Pitest no necesita configurarse adicionalmente si usa JUnit 4. La personalización se realiza en el bloque pitest :
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
}Configuración idiomática y más portátil:
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 )
} A partir de Gradle 8.1, se puede utilizar la asignación de propiedad simple para configurar el complemento (en lugar del método 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
} La configuración en Gradle es el código maravilloso real que hace que todas las tareas sean muy intuitivas. Todos los valores esperados por PIT deben pasarse como tipos correspondientes. Solo hay una diferencia importante. Para los parámetros donde el PIT espera una lista separada por coma de cadenas en una configuración de gradle, se debe utilizar una lista de cadenas (consulte outputFormats en el ejemplo anterior).
Consulte la documentación del box para obtener una lista de todos los parámetros de línea de comandos disponibles. El formato de parámetro esperado en una configuración de complemento se puede tomar de PitestPluginextension.
Para facilitar la vida, taskClasspath , mutableCodePaths , sourceDirs , reportDir , verbosity y pitestVersion se establecen automáticamente mediante el complemento. Además, sourceDirs , reportDir , verbosity y pitestVersion pueden ser anulados por un usuario.
Hay algunos parámetros específicos para el complemento de Gradle:
testSourceSets : define los conjuntos de fuente de prueba que deben ser utilizados por PIT (por fuga predeterminada.mainSourceSets : define los conjuntos de fuente principales que deben ser utilizados por PIT (por fuentes predeterminadas.mainProcessJvmArgs - Argumentos JVM que se utilizarán al lanzar el proceso de PIT principal; Tenga en cuenta que el PIT en sí lanza otros procesos Java para la ejecución de pruebas de mutación y, por lo general, jvmArgs deben usarse para aumentar el tamaño máximo de la memoria (ver #7);additionalMutableCodePaths : clases adicionales para mutar (útil para pruebas de integración con código de producción en un módulo diferente - ver #25)useClasspathFile : habilita la aprobación de clases adicionales como contenido de archivo (útil para usuarios de Windows con muchos elementos de classpath, deshabilitado de forma predeterminada)fileExtensionsToFilter : proporciona la capacidad de filtrar extensiones de archivos adicionales desde PIT ClassPath (ver #53)Por ejemplo:
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 ejecuta pruebas en un JVM independiente del JVM utilizado por Gradle para ejecutar pruebas. Si sus pruebas requieren algunas propiedades del sistema, debe pasarlas para hoy, ya que el complemento no lo hará por usted:
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 " ))
} Como se informó en el #170 Idea IntelliJ muestra advertencias sobre la configuración de los campos finales (de la configuración perezosa) en build.gradle . No es un problema real ya que Gradle intercepta internamente esas llamadas y usa un setter. Sin embargo, las personas que prefieren no tener (menos) advertencias a costa del código menos legible pueden usar setters en su lugar, por ejemplo, por ejemplo:
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 se puede usar en proyectos de múltiples módulos. La dependencia de Gradle-Pitest-Plugin debe agregarse a la configuración BuildScript en el proyecto raíz, mientras que el complemento debe aplicarse en todos los subproyectos que deben procesarse con PIT. Un fragmento de muestra de build.gradle ubicado para el proyecto root:
// 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 )
}
}
} Es posible agregar el informe de Pitest para el proyecto múltiple mediante el complemento info.solidsoft.pitest.aggregator y tareas pitestReportAggregate . El proyecto raíz debe configurarse correctamente para usar 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 )
}
}
} Después de la ejecución de tareas pitest pitestReportAggregate , el informe agregado se colocará en el directorio ${PROJECT_DIR}/build/reports/pitest .
Es posible mutar el código ubicado en diferentes subproyectos. Gradle internamente no confía en el directorio de salida de otro subproyecto, pero construye JAR y usa clases de él. Para el pozo, esos son dos conjuntos diferentes de archivos de clase, por lo que para que funcione, se requiere definir ambos mainSourceSets y additionalMutableCodePaths . Por ejemplo:
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))
}
}Lo anterior es la forma en que el equipo de Gradle recomendado, pero en casos específicos, la solución más simple también debería funcionar:
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)
}
}La construcción mínima de proyectos mínimos de trabajo está disponible en el suite de pruebas funcionales.
Los complementos de prueba se utilizan para admitir diferentes marcos de prueba que JUnit4.
Comenzando con esta versión, la configuración requerida para usar PIT con JUnit 5 se ha simplificado a lo siguiente:
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 " )
}Tenga en cuenta . PIT 1.9.0 requiere Pitest-Junit5-Plugin 1.0.0+. JUnit Júpiter 5.8 (Plataforma Junit 1.8) requiere Pitest-Junit5-Plugin 0.15+, mientras que 5.7 (1.7) requiere 0.14. Establezca la versión del complemento derecho para la versión Junit 5 utilizada en su proyecto para evitar errores de tiempo de ejecución (como `nosuchmethoderror: 'java.util.optional org.junit.platform.commons.util.annotationutils.findannotation (java.lang.class, java.lang.class, boolean)')).
El ejemplo de trabajo mínimo para Junit 5 está disponible en la suite de pruebas funcionales.
Para mezclar Junit 5 con otros complementos de boxes, puede leer esta sección en mi publicación de blog.
Para habilitar complementos de boxes, es suficiente para agregarlo a la configuración de Pitest en el cierre de BuildScript. Por ejemplo:
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 " )
}El ejemplo de trabajo mínimo está disponible en la suite de pruebas funcionales.
Tenga en cuenta. En Gradle-Pitest-Plugin <1.5.0, la configuración pitest tuvo que crearse en el alcance buildscript para el proyecto root. Tenga en cuenta. Comenzando con PIT 1.6.7 ya no es necesario establecer el parámetro de configuración testPlugin . También está en desuso en el complemento de Gradle.
Cada versión de Gradle-Pitest-Plugin de forma predeterminada usa una versión PIT predefinida. Por lo general, esta la última versión lanzada de PIT disponible en el momento de lanzar una versión de complemento. Se puede anular utilizando el parámetro pitestVersion en un cierre de configuración pitest .
Tenga en cuenta que, en algunos casos, podría haber algunos problemas al usar versiones PIT no predeterminadas.
Si no se indica de lo contrario, Gradle-Pitest-Plugin 1.9.x de forma predeterminada usa PIT 1.9.x, 1.7.x usa PIT 1.7.x, etc. La versión mínima de PIT compatible es 1.7.1.
Comenzando con la versión 1.7.0 Gradle-Pitest-Plugin requiere Gradle 6.4. La última versión con el soporte de Gradle 5.x (5.6+) es 1.6.0. La versión actual se probó automáticamente con el Gradle 6.4, 6.9.1 y 7.4.2 bajo Java 11. Las pruebas con Java 11+ se limitan a las versiones compatibles de Gradle y PIT.
El apoyo experimental para Java 17 se puede probar con 1.7.0+.
Comenzando con la versión 1.3.0, los binarios producidos requieren Java 8 (como un JDK utilizado para ejecutar una construcción de Gradle). Sin embargo, con Java 17 LTS lanzado en septiembre de 2021, comenzando con Gradle-Pitest-Plugin 1.9.0, el soporte para JDK <11 está en desuso (ver #299).
Consulte el archivo ChangeLog para obtener una lista más detallada de los cambios en el complemento en sí.
Gradle no proporciona una forma incorporada de anular la configuración del complemento a través de la línea de comandos, pero Gradle-Override-Plugin se puede usar para hacerlo.
Después de aplicar gradle-Override-Plugin en su proyecto, es posible hacer lo siguiente:
./gradlew pitest -Doverride.pitest.reportDir=build/pitReport -Doverride.pitest.threads=8
Nota. El mecanismo debe funcionar bien para las propiedades de cadena y numérica, pero existen limitaciones con el soporte de listas/conjuntos/mapas y valores booleanos.
Para obtener más información, consulte la página web del proyecto.
Gradle-Pitest-Plugin de forma predeterminada utiliza una versión PIT correspondiente (con el mismo número). El complemento se libera solo si hay cambios internos o es necesario ajustar a los cambios en la versión más reciente de PIT. Existe un mecanismo dedicado para permitir usar la última versión de box (por ejemplo, una versión de corrección de errores) o de rebajar el pozo en caso de problemas detectados. Para anular una versión predeterminada, es suficiente establecer la propiedad pitestVersion en el cierre de configuración pitest .
pitest {
pitestVersion = ' 2.8.1-the.greatest.one '
}pitest {
pitestVersion.set( " 2.8.1-the.greatest.one " )
}En caso de errores detectados cuando se usa la última versión disponible del complemento con la versión más nueva de PIT, plantee un problema.
Colocar informes PIT directamente en ${PROJECT_DIR}/build/reports/pitest se puede habilitar con timestampedReports Propiedad de configuración:
pitest {
timestampedReports = false
}pitest {
timestampedReports.set( false )
}Ocasionalmente, puede ser útil depurar una ejecución de Gradle-Pitest-Plugin o una ejecución de PIT (por ejemplo, NPE en PIT) para proporcionar un informe de error sensible.
La ejecución de Gradle-Pitest-Plugin se puede depurar de forma remota para agregar -Dorg.gradle.debug=true a la línea de comando.
Sin embargo, a medida que PIT se inicia como un proceso separado para depurar su ejecución, los siguientes argumentos deben agregarse a la configuración del complemento:
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 " ))
}La respuesta corta es: no directamente. Debido a algunas incompatibilidades entre las aplicaciones Java "estándar" y las aplicaciones Java Android en Gradle, el complemento no admite el posterior. Afortunadamente, hay una bifurcación de Android del complemento mantenido por Karol Wrótniak que proporciona una versión modificada que admite aplicaciones Android (pero por otro lado no funciona con aplicaciones Java estándar).
Gradle-Pitest Plugin 1.5.0 finalmente relajó la forma en que (dónde) se ha colocado la configuración pitest (#62) que también estaba generando advertencias de deprecación en Gradle 6+. Este cambio no es compatible con versiones anteriores y, como resultado, la migración manual debe hacerse; consulte las notas de la versión. Esto afecta solo al proyecto con complementos personalizados externos.
Importante . Como el complemento JUnit 5 para PIT es definitivamente el más popular, comenzando con 1.4.7, existe una forma simplificada de cómo podría configurarse con junit5PluginVersion (que definitivamente se recomienda ). Vea mi publicación de blog para averiguar cómo migrar (también resuelve el problema de compatibilidad con 1.5.0+).
verbosity introducida con PIT 1.7.1) Gradle-Pitest-Plugin clonado desde el repositorio se puede construir usando el comando Gradle:
./gradlew build
La forma más fácil de hacer un frasco con cambios locales visibles en otro proyecto es instalarlo en el repositorio local de Maven:
./gradlew install
También hay pruebas funcionales básicas escritas usando Nebula-Test que se pueden ejecutar con:
./gradlew funcTest
Gradle-Pitest-Plugin ha sido escrito por Marcin Zajączkowski con la ayuda de los contribuyentes. Se puede contactar al autor directamente por correo electrónico: mszpak att wp dott pl. También está el blog de Marcin disponible: Solid Soft - El código de trabajo no es suficiente.
El complemento seguramente tiene algunos errores y características faltantes. Se pueden informar utilizando un rastreador de problemas. Sin embargo, a menudo es una mejor idea enviar primero una pregunta a la lista de correo de PIT.
El complemento tiene licencia bajo los términos de la licencia Apache, versión 2.0.