Eventualmente
Esta página fue traducida por PageTurner AI (beta). No está respaldada oficialmente por el proyecto. ¿Encontraste un error? Reportar problema →
A partir de Kotest 5.7, las funciones de pruebas no deterministas se han movido al módulo kotest-assertions-core, y
están disponibles bajo el nuevo paquete io.kotest.assertions.nondeterministic. Las versiones anteriores de estas
funciones siguen disponibles, pero están obsoletas.
Probar código no determinista puede ser complicado. Puede que necesites gestionar hilos, tiempos de espera, condiciones de carrera y la imprevisibilidad de cuándo ocurren los eventos.
Por ejemplo, si estuvieras verificando que una escritura de archivo asíncrona se completó correctamente, necesitas esperar hasta que la operación de escritura haya finalizado y se haya volcado al disco.
Algunos enfoques comunes para estos problemas son:
-
Usar callbacks que se invocan una vez completada la operación. El callback puede usarse entonces para verificar que el estado del sistema es el esperado. Pero no todas las operaciones ofrecen funcionalidad de callback.
-
Bloquear el hilo usando
Thread.sleepo suspender una función condelay, esperando a que la operación termine. El umbral de espera debe ser lo suficientemente alto para asegurar que las operaciones se completen tanto en máquinas rápidas como lentas. Además, significa que tu prueba permanecerá inactiva esperando el tiempo de espera incluso si el código se completa rápidamente en una máquina veloz. -
Usar un bucle con espera y reintento, pero entonces necesitas escribir código repetitivo para controlar el número de iteraciones, manejar ciertas excepciones y fallar en otras, asegurar que el tiempo total no exceda el máximo, etc.
-
Usar countdown latches y bloquear hilos hasta que los latches sean liberados por la operación no determinista - la implementación parallelRunner de Kotest muestra cómo hacerlo. Esto puede funcionar bien si puedes inyectar los latches en los lugares apropiados, pero al igual que con los callbacks, no siempre es posible que el código bajo prueba se integre con un latch.
Como alternativa a las soluciones anteriores, Kotest proporciona la función eventually que resuelve el caso de uso común:
"Espero que este código se ejecute correctamente tras un breve periodo de tiempo".
eventually funciona invocando periódicamente una lambda dada, ignorando excepciones específicas, hasta que la lambda se ejecuta correctamente, se alcanza un tiempo de espera, o se supera el número máximo de iteraciones. Esto es flexible y perfecto para probar código no determinista. eventually puede personalizarse en cuanto a los tipos de excepciones a manejar, cómo se considera éxito o fracaso de la lambda, con un listener, etc.
API
Hay dos formas de usar eventually. La primera es simplemente proporcionando una duración usando el tipo Duration de Kotlin,
seguido del código que debería ejecutarse correctamente sin lanzar excepciones.
Por ejemplo:
eventually(5.seconds) {
userRepository.getById(1).name shouldBe "bob"
}
La segunda es mediante un bloque de configuración. Este método debe usarse cuando necesitas establecer más opciones además de la duración. También permite compartir la configuración entre múltiples invocaciones de eventually.
Por ejemplo:
val config = eventuallyConfig {
duration = 1.seconds
interval = 100.milliseconds
}
eventually(config) {
userRepository.getById(1).name shouldBe "bob"
}