Ir al contenido principal
Versión: 5.7.x

Modos de Aislamiento

[Traducción Beta No Oficial]

Esta página fue traducida por PageTurner AI (beta). No está respaldada oficialmente por el proyecto. ¿Encontraste un error? Reportar problema →

Todas las especificaciones te permiten controlar cómo el motor de pruebas crea instancias de Specs para los casos de prueba. Este comportamiento se denomina modo de aislamiento y está controlado por una enumeración IsolationMode. Existen tres valores: SingleInstance, InstancePerLeaf e InstancePerTest.

Si deseas que las pruebas se ejecuten en instancias nuevas de la especificación - para permitir que el estado compartido entre pruebas se reinicie - puedes cambiar el modo de aislamiento.

Esto se puede hacer mediante DSL como:

class MyTestClass : WordSpec({
isolationMode = IsolationMode.SingleInstance
// tests here
})

O si prefieres sobrescribir funciones, puedes anular fun isolationMode(): IsolationMode:

class MyTestClass : WordSpec() {
override fun isolationMode() = IsolationMode.SingleInstance
init {
// tests here
}
}
peligro

El valor predeterminado en Kotest es Single Instance, igual que en ScalaTest (la inspiración de este framework), Jest, Jasmine y otros frameworks Javascript, pero diferente a JUnit.

Instancia Única

El modo de aislamiento predeterminado es SingleInstance, donde se crea una instancia de la clase Spec y luego cada caso de prueba se ejecuta sucesivamente hasta completar todas las pruebas.

Por ejemplo, en la siguiente especificación, se imprimiría el mismo id tres veces porque se usa la misma instancia para todas las pruebas.

class SingleInstanceExample : WordSpec({
val id = UUID.randomUUID()
"a" should {
println(id)
"b" {
println(id)
}
"c" {
println(id)
}
}
})

Instancia por Prueba

El siguiente modo es IsolationMode.InstancePerTest, donde se creará una nueva especificación para cada caso de prueba, incluyendo contextos internos. Es decir, los contextos externos se ejecutarán como pruebas "independientes" en su propia instancia de la especificación. Un ejemplo lo aclarará.

class InstancePerTestExample : WordSpec() {

override fun isolationMode(): IsolationMode = IsolationMode.InstancePerTest

init {
"a" should {
println("Hello")
"b" {
println("From")
}
"c" {
println("Sam")
}
}
}
}

Fíjate cómo hemos sobrescrito aquí la función isolationMode.

Al ejecutarse, se imprimirá lo siguiente:

Hello
Hello
From
Hello
Sam

Esto ocurre porque el contexto externo (prueba "a") se ejecuta primero. Luego se ejecuta de nuevo para la prueba "b", y otra vez para la prueba "c". Cada vez en una instancia limpia de la clase Spec. Es muy útil cuando queremos reutilizar variables.

Otro ejemplo mostrará cómo se reinician las variables.

class InstancePerTestExample : WordSpec() {

override fun isolationMode(): IsolationMode = IsolationMode.InstancePerTest

val counter = AtomicInteger(0)

init {
"a" should {
println("a=" + counter.getAndIncrement())
"b" {
println("b=" + counter.getAndIncrement())
}
"c" {
println("c=" + counter.getAndIncrement())
}
}
}
}

Esta vez, la salida será:

a=0 a=0 b=1 a=0 c=1

Instancia por Hoja

El siguiente modo es IsolationMode.InstancePerLeaf, donde se crea una nueva especificación para cada caso de prueba hoja - excluyendo contextos internos. Es decir, los contextos internos solo se ejecutan como parte de la "ruta" hacia una prueba externa. Un ejemplo lo aclarará.

class InstancePerLeafExample : WordSpec() {

override fun isolationMode(): IsolationMode = IsolationMode.InstancePerLeaf

init {
"a" should {
println("Hello")
"b" {
println("From")
}
"c" {
println("Sam")
}
}
}
}

Al ejecutarse, se imprimirá lo siguiente:

Hello
From
Hello
Sam

Esto se debe a que primero se ejecuta el contexto externo - prueba "a" - seguido de la prueba "b" en la misma instancia. Luego se crea una nueva especificación, se ejecuta nuevamente la prueba "a", seguida de la prueba "c".

Otro ejemplo mostrará cómo se reinician las variables.

class InstancePerLeafExample : WordSpec() {

override fun isolationMode(): IsolationMode = IsolationMode.InstancePerLeaf

val counter = AtomicInteger(0)

init {
"a" should {
println("a=" + counter.getAndIncrement())
"b" {
println("b=" + counter.getAndIncrement())
}
"c" {
println("c=" + counter.getAndIncrement())
}
}
}
}

Esta vez, la salida será:

a=0 b=1 a=0 c=1

Modo de Aislamiento Global

En lugar de configurar el modo de aislamiento en cada especificación, podemos establecerlo globalmente en la configuración del proyecto o mediante una propiedad del sistema.

Propiedad del Sistema

Para establecer el modo de aislamiento global desde la línea de comandos, usa la propiedad del sistema kotest.framework.isolation.mode con uno de los valores:

  • InstancePerTest

  • InstancePerLeaf

  • SingleInstance

nota

Los valores distinguen entre mayúsculas y minúsculas.

Configuración

Consulta la documentación sobre cómo configurar la configuración global del proyecto, y luego añade el modo de aislamiento que quieras como predeterminado. Por ejemplo:

class ProjectConfig: AbstractProjectConfig() {
override val isolationMode = IsolationMode.InstancePerLeaf
}
nota

Configurar un modo de aislamiento en un Spec siempre tendrá prioridad sobre la configuración global del proyecto.