es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Detener/Cancelar la ejecución de la prueba JUnit 5 (iniciada programáticamente)

Tengo algunas pruebas de JUnit 5, que se ejecutan y se inician dentro de un contenedor OSGi.
El código para iniciar la ejecución de la prueba se ve algo así:

LauncherConfig launcherConfig = LauncherConfig.builder().addTestEngines( new JupiterTestEngine() ).build();
Launcher launcher = LauncherFactory.create( launcherConfig );

LauncherDiscoveryRequest request = LauncherDiscoveryRequestBuilder.request()
     .selectors( selectClass( testName ) )
     .build();
TestPlan testPlan = launcher.discover( request );

launcher.execute( request );

Dado que algunas de estas pruebas requieren pasos manuales con hardware físico, las pruebas no se ejecutan en un entorno de integración continua (CI) y están destinadas a ser ejecutadas manualmente por un probador. Por lo tanto, las pruebas pueden tardar bastante tiempo (especialmente si el probador no realiza los pasos manuales requeridos).

Pregunta: ¿Cómo puedo detener la ejecución de una prueba en curso?

Antecedentes: Me gustaría asegurarme de que solo se ejecute una prueba a la vez para evitar interferencias entre las pruebas. Por otro lado, no quiero que una prueba “incompleta” bloquee la ejecución de la prueba para siempre.

Tags:  ,

Answer

  1. Avatar for davy.ai

    Para detener la ejecución de una prueba en curso, se puede utilizar el método Launcher#registerTestExecutionListeners para registrar un TestExecutionListener personalizado que escuche las interrupciones del teclado. Una vez que el oyente esté registrado, la ejecución de la prueba se puede detener por parte del probador utilizando una interrupción del teclado (generalmente Ctrl-C).

    Aquí tienes un ejemplo de implementación de dicho oyente:

    import org.junit.platform.engine.TestExecutionResult;
    import org.junit.platform.launcher.TestExecutionListener;
    import org.junit.platform.launcher.TestIdentifier;
    
    import java.util.concurrent.atomic.AtomicBoolean;
    
    public class InterruptableTestExecutionListener implements TestExecutionListener {
    
        private final AtomicBoolean stopExecution = new AtomicBoolean(false);
    
        @Override
        public void executionSkipped(TestIdentifier testIdentifier, String reason) {
            checkInterrupted();
        }
    
        @Override
        public void executionStarted(TestIdentifier testIdentifier) {
            checkInterrupted();
        }
    
        @Override
        public void executionFinished(TestIdentifier testIdentifier, TestExecutionResult testExecutionResult) {
            checkInterrupted();
        }
    
        @Override
        public void executionAborted(TestIdentifier testIdentifier, Throwable throwable) {
            checkInterrupted();
        }
    
        private void checkInterrupted() {
            if (stopExecution.get()) {
                throw new TestInterruptedRuntimeException("La ejecución de la prueba fue interrumpida");
            }
        }
    
        public void stopExecution() {
            stopExecution.set(true);
        }
    
        public boolean isExecutionStopped() {
            return stopExecution.get();
        }
    
        private static class TestInterruptedRuntimeException extends RuntimeException {
            public TestInterruptedRuntimeException(String message) {
                super(message);
            }
        }
    }
    

    Para utilizar este oyente, puedes crear una instancia de él, registrarlo con la instancia de Launcher utilizando Launcher#registerTestExecutionListeners y revisar periódicamente si se ha establecido la bandera stopExecution. Si es así, puedes llamar a Launcher#stop() para detener la ejecución de la prueba actual. Aquí tienes un ejemplo:

    LauncherConfig launcherConfig = LauncherConfig.builder().addTestEngines(new JupiterTestEngine()).build();
    Launcher launcher = LauncherFactory.create(launcherConfig);
    
    InterruptableTestExecutionListener executionListener = new InterruptableTestExecutionListener();
    launcher.registerTestExecutionListeners(executionListener);
    
    LauncherDiscoveryRequest request = LauncherDiscoveryRequestBuilder.request()
            .selectors(selectClass(testName))
            .build();
    TestPlan testPlan = launcher.discover(request);
    
    launcher.execute(request);
    
    while (!executionListener.isExecutionStopped()) {
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            // Ignorar
        }
    }
    
    launcher.stop();
    

Comments are closed.