Agrupación de Pruebas con Etiquetas
Esta página fue traducida por PageTurner AI (beta). No está respaldada oficialmente por el proyecto. ¿Encontraste un error? Reportar problema →
A veces no quieres ejecutar todas las pruebas y Kotest proporciona tags (etiquetas) para determinar qué pruebas se ejecutan en tiempo de ejecución. Las etiquetas son objetos que heredan de io.kotest.core.Tag.
Por ejemplo, para agrupar pruebas por sistema operativo podrías definir estas etiquetas:
object Linux : Tag()
object Windows : Tag()
Alternativamente, las etiquetas pueden definirse usando la clase NamedTag. Al usar esta clase, sigue estas reglas:
Una etiqueta no puede ser nula o estar vacía.
Una etiqueta no puede contener espacios en blanco.
Una etiqueta no puede contener caracteres de control ISO.
Una etiqueta no debe contener ninguno de los siguientes caracteres:
- !: signo de exclamación
- (: paréntesis izquierdo
- ): paréntesis derecho
- &: et comercial (ampersand)
- |: barra vertical (pipe)
Por ejemplo:
val tag = NamedTag("Linux")
Si dos objetos de etiqueta tienen el mismo nombre simple (incluso en paquetes diferentes), se tratan como la misma etiqueta.
Añadir etiquetas a las pruebas
Etiquetado de pruebas
Las pruebas pueden etiquetarse en varios niveles. Primero, los casos de prueba pueden tener etiquetas añadidas mediante la config de la prueba. Ten en cuenta que cualquier etiqueta anidada hereda las etiquetas de sus padres.
class MyTest : FunSpec() {
init {
test("should run on Windows").config(tags = setOf(Windows)) {
// ...
}
test("should run on Linux").config(tags = setOf(Linux)) {
// ...
}
context("should run on Windows and Linux").config(tags = setOf(Windows, Linux)) {
test("and nested tests") { // implicity has windows and linux tags added
}
}
}
}
Etiquetado de specs
En segundo lugar, puedes añadir etiquetas a nivel de spec, ya sea mediante la función tags en el propio spec o mediante la anotación @Tags. Cualquier etiqueta añadida de esta manera se aplica implícitamente a todas las pruebas.
Al etiquetar pruebas de esta manera, la clase spec aún necesitará instanciarse para examinar las etiquetas de cada prueba, porque la prueba misma puede definir etiquetas adicionales. Por lo tanto, no confíes en este método si quieres evitar instanciar clases por completo; en su lugar, consulta @RequiresTag.
@Tags("Foo") // applied to all tests in this spec
private class TaggedSpec : ExpectSpec() {
init {
tags(Windows) // applied to all tests in this spec
expect("should run on Windows") {
// ...
}
}
}
Cualquier etiqueta añadida mediante @Tags no evita que el spec se instancie, ya que el motor necesita comprobar si hay etiquetas añadidas mediante código. Si quieres evitar completamente que un spec se instancie, usa @RequiresTag.
@RequiresTag
Finalmente, puedes usar la anotación @RequiresTag. Esta solo verifica que todas las etiquetas referenciadas estén presentes y, si no, omitirá el spec por completo. Esta es una distinción importante porque con la otra anotación - @Tags - el spec aún necesitará instanciarse para comprobar las etiquetas añadidas mediante el DSL. Esto puede resultar contraintuitivo.
Por ejemplo, esta spec se omitiría y no se instanciaría a menos que las etiquetas Linux y Mysql estuvieran especificadas en tiempo de ejecución.
@RequiresTag("Linux", "Mysql")
class MyTestClass : FunSpec()
Ten en cuenta que al usar anotaciones, pasas el nombre de cadena de la etiqueta, no la instancia de la etiqueta en sí.
Ejecución con etiquetas
Al invocar el ejecutor de pruebas con una propiedad del sistema kotest.tags o una variable de entorno KOTEST_TAGS, puedes controlar qué pruebas se ejecutan. La expresión a pasar es una expresión booleana simple que utiliza operadores: &, |, !, con paréntesis para asociación.
Por ejemplo: Tag1 & (Tag2 | Tag3)
Proporciona los nombres simples de los objetos de etiqueta (sin paquete) al ejecutar las pruebas. Por ejemplo, una etiqueta creada como val mytag = NamedTag("A") usaría el nombre de etiqueta A.
¡Presta atención al uso de mayúsculas y minúsculas! Las etiquetas distinguen entre mayúsculas y minúsculas.
Ejemplo: Para ejecutar solo pruebas etiquetadas con Linux, pero no con Database, invocarías Gradle usando la variable de entorno (desde Kotest 6.1.0).
KOTEST_TAGS="Linux & !Database" gradle check
O usando la propiedad del sistema desde la línea de comandos.
gradle test -Dkotest.tags="Linux & !Database"
O especificando la propiedad del sistema en tu script de compilación.
tasks.withType<Test>().configureEach {
systemProperty("kotest.tags", "Linux & !Database")
}
Prefiere la variable de entorno ya que funciona en todas las plataformas, a menos que estés en una versión anterior de Kotest (anterior a 6.1) o necesites especificar las etiquetas en tu script de compilación de Gradle en lugar de en la línea de comandos.
Si ninguna prueba raíz está activa en tiempo de ejecución, los callbacks beforeSpec y afterSpec no se invocarán.
Operadores de expresiones de etiquetas
Operadores (en orden descendente de precedencia)
| Operator | Description | Example |
|---|---|---|
| ! | not | !macos |
| & | and | linux & integration |
| | | or | windows | microservice |
Herencia de etiquetas
Por defecto, la anotación @Tags solo se considera en el Spec inmediato donde se aplicó. Sin embargo, un Spec también puede heredar etiquetas de superclases e interfaces. Para habilitar esto, activa tagInheritance = true en tu configuración de proyecto.
Ejemplos
Considera este ejemplo:
@Tags("Linux")
class MyTestClass : FunSpec({
tags(UnitTest)
beforeSpec { println("Before") }
test("A").config(tags = setOf(Mysql)) {}
test("B").config(tags = setOf(Postgres)) {}
test("C") {}
})
| Runtime Tags | Spec Created | Callbacks | Outcome |
|---|---|---|---|
| kotest.tags=Linux | yes | yes | A, B, C are executed because all tests inherit the Linux tag from the annotation |
| kotest.tags=Linux & Mysql | yes | yes | A is executed only because all tests have the Linux tag, but only A has the Mysql tag |
| kotest.tags=!Linux | no | no | No tests are executed, and the MyTestClass is not instantiated because we can exclude it based on the tags annotation |
| kotest.tags=!UnitTest | yes | no | No tests are executed because all tests inherit UnitTest from the tags function. MyTestClass is instantiated in order to retrieve the tags defined in the class. The beforeSpec callback is not executed because there are no active tests. |
| kotest.tags=Mysql | yes | yes | A is executed only, because that is the only test marked with Mysql |
| kotest.tags=!Mysql | yes | yes | B, C are executed only, because A is excluded by being marked with Mysql |
| kotest.tags=Linux & !Mysql | yes | yes | B, C are executed only, because all tests inherit Linux from the annotation, but A is excluded by the Mysql tag |
Gradle
Se requiere especial atención en tu configuración de Gradle al usar propiedades del sistema
Para usar Propiedades del Sistema (-Dx=y), Gradle debe estar configurado para propagarlas a los ejecutores de pruebas, y se debe agregar una configuración adicional a tus pruebas:
Groovy:
test {
//... Other configurations ...
systemProperties = System.properties
}
Kotlin DSL de Gradle:
val test by tasks.getting(Test::class) {
// ... Other configurations ...
systemProperties = System.getProperties().asIterable().associate { it.key.toString() to it.value }
}
Esto garantizará que la propiedad del sistema sea leída correctamente por la JVM.