Ir al contenido principal
Versión: 6.1

Ganchos del ciclo de vida

[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 →

Es muy común en las pruebas querer realizar alguna acción antes y después de un test, o antes y después de todos los tests en el mismo archivo. Es en estos ganchos del ciclo de vida donde se ejecutaría cualquier lógica de configuración/desmontaje necesaria para una prueba.

Kotest ofrece una amplia variedad de ganchos que pueden definirse directamente dentro de un Spec. Al final de esta sección encontrarás un listado de los ganchos disponibles y cuándo se ejecutan.

[Casos avanzados]

Para casos más avanzados, como crear plugins distribuibles, ganchos reutilizables o eventos que ocurren fuera de un Spec (como project-started o project-finished), consulta las extensiones.

Existen principalmente dos formas de definir estos ganchos en Kotest, funcionalmente equivalentes pero con diferente estilo. Elige la que tú y tu equipo prefiráis.

Métodos DSL

La primera es usar los métodos DSL disponibles dentro de un Spec que aceptan una lambda para la lógica del gancho. Por ejemplo, podemos invocar beforeTest o afterTest (u otros) directamente junto a nuestros tests.

class TestSpec : FreeSpec() {
init {

beforeTest {
println("Starting a test $it")
}

afterTest { (test, result) ->
println("Finished spec with result $result")
}

"this test" - {
"be alive" {
println("Johnny5 is alive!")
}
}
}
}
nota

Puedes usar afterProject como método DSL, pero no existe un equivalente beforeProject, porque cuando el framework llega a la etapa de ejecutar un Spec, ¡el proyecto ya ha comenzado!

Type-aliases para lambdas

Dado que estos métodos DSL aceptan funciones, podemos extraer la lógica a una función y reutilizarla en varios lugares. El gancho beforeTest acepta una función de tipo suspend (TestCase) -> Unit. Existen typealiases para cada firma de función para mantener tu código simple.

Por ejemplo, para crear una lambda beforeTest reutilizable:

val startTest: BeforeTest = {
println("Starting a test $it")
}

class TestSpec : FreeSpec({

// used once
beforeTest(startTest)

"test1" { }
})

class OtherSpec : FreeSpec({

// used again
beforeTest(startTest)

"test2" { }
})

Sobrescritura de métodos

La segunda forma de crear ganchos es sobrescribir la función apropiada en el Spec. Por ejemplo, para añadir un gancho previo al test, podemos sobrescribir la función beforeTest:

class TestSpec : FreeSpec() {

override suspend fun beforeTest(testCase: TestCase) {
println("Starting a test $testCase")
}

init {
"this test" - {
"be alive" {
println("Johnny5 is alive!")
}
}
}
}

Ganchos disponibles

Kotest proporciona callbacks para varios eventos de tests y Specs.

Para entender correctamente todos los callbacks, es importante comprender los dos valores posibles de TestType:

  • Container - un contenedor que puede incluir otros tests

  • Test - un test hoja que no puede contener tests anidados

Ganchos del ciclo de vida de tests

CallbackDescription
before-containerInvoked directly before each test with type TestType.Container, with the TestCase instance as a parameter. If the test is marked is skipped, then this callback won't be invoked.
after-containerInvoked immediately after a TestCase with type TestType.Container, with the TestResult of that test. If a test was skipped then this callback will not be invoked.

The callback will execute even if the test fails.
before-eachInvoked directly before each test with type TestType.Test, with the TestCase instance as a parameter. If the test is marked is skipped, then this callback won't be invoked.
after-eachInvoked immediately after a TestCase with type TestType.Test, with the TestResult of that test. If the test was skipped then this callback will not be invoked.

The callback will execute even if the test fails.
before-anyInvoked directly before each test with any TestType, with the TestCase instance as a parameter. If the test is marked is skipped, then this callback won't be invoked.
after-anyInvoked immediately after a TestCase with any TestType, with the TestResult of that test. If the test was skipped then this callback will not be invoked.

The callback will execute even if the test fails.
before-testThis callback is an alias for beforeAny.
after-testThis callback is an alias for afterAny.
before-invocationInvoked before each 'run' of a test, with a flag indicating the iteration number. This callback is useful if you have set a test to have multiple invocations via config and want to do some setup / teardown between runs.

If you are running a test with the default single invocation then this callback is effectively the same as beforeTest.
after-invocationInvoked after each 'run' of a test, with a flag indicating the iteration number. This callback is useful if you have set a test to have multiple invocations via config and want to do some setup / teardown between runs.

If you are running a test with the default single invocation then this callback is effectively the same as afterTest.

Observa que before-each y before-container están limitados a un tipo de test específico (hoja o contenedor), mientras que before-any se invocará para ambos. Lo mismo aplica para after-each, after-container y after-any.

Ganchos del ciclo de vida del Spec

CallbackDescription
before-specInvoked after the Engine instantiates a spec to be used as part of a test execution.

The callback is provided with the Spec instance that the test will be executed under.

If a spec is instantiated multiple times - for example, if InstancePerRoot isolation mode is used, then this callback will be invoked for each instance created, just before the first test is executed for that spec.

This callback should be used if you need to perform setup each time a new spec instance is created.

This callback runs before any test level hooks functions are invoked.
after-specIs invoked after all the tests that are part of a particular spec instance have completed.

If a spec is instantiated multiple times - for example, if InstancePerRoot isolation mode is used, then this callback will be invoked for each instantiated spec, after the tests that are applicable to that spec instance have returned.

This callback should be used if you need to perform cleanup after each individual spec instance.

This callback runs after any test level callbacks have been invoked.

In case there is any exception in beforeSpec, afterSpec will be skipped.