¿Puedo ejecutar automáticamente casos de prueba de JUnit una vez con todos los registros habilitados y una vez con todos los registros deshabilitados?

StackOverflow https://stackoverflow.com/questions/945659

Pregunta

Encontré una solución, vea mi propia respuesta a continuación.¿Alguien tiene uno más elegante?

Quiero hacer esto para aumentar la cobertura del código y encontrar errores sutiles.

Supongamos que se probará la siguiente clase:

public class Foo {
    private final Logger logger = LoggerFactory.getLogger(Foo.class);
    public void bar() {
        String param=[..];
        if(logger.isInfoEnabled()) logger.info("A message with parameter {}", param);

        if(logger.isDebugEnabled()) {
            // some complicated preparation for the debug message
            logger.debug([the debug message]);
        }
    }
}

y la siguiente clase de prueba:

public class FooTest {
    @Test
    public void bar() {
        Foo foo=new Foo();
        foo.bar();
    }
}

Una herramienta de cobertura de código como, por ejemplo.Cobertura informará correctamente que sólo se han comprobado algunas de las ramas condicionales.

La información y la depuración se activan o desactivan para el registrador.

Además de verse mal en su puntaje de cobertura, esto representa un riesgo real.

¿Qué pasa si hay algún efecto secundario causado por el código dentro de if(logger.isDebugEnabled())?¿Qué pasa si su código solo funciona si DEBUG está habilitado y falla estrepitosamente si el nivel de registro está configurado en INFO?(Esto realmente sucedió en uno de nuestros proyectos :p)

Entonces, mi conclusión es que el código que contiene declaraciones del registrador siempre debe probarse una vez con todos los registros habilitados y una vez con todos los registros deshabilitados...

¿Hay alguna manera de hacer algo así con JUnit?Sé cómo habilitar o deshabilitar globalmente todos mis registros en Logback, por lo que el problema es:¿Cómo puedo ejecutar las pruebas dos veces, una con el registro habilitado y otra con el registro deshabilitado?

PD.Soy consciente de esta pregunta pero no creo que esto sea un duplicado.Estoy menos preocupado por los valores de cobertura absoluta sino por errores sutiles y difíciles de encontrar que podrían estar contenidos dentro de un if(logger.isDebugEnabled()).

¿Fue útil?

Solución

He resuelto este problema mediante la implementación de una clase base que las clases de prueba debe extenderse si se desea tal funcionalidad.

El artículo Escritura de una prueba unitaria parametrizada contenida la solución.

Consulte LoggingTestBase para la clase base tala y LoggingTestBaseExampleTest para un ejemplo simple que lo está usando.

Cada método de ensayo contenida se ejecuta tres veces:

1. Se ejecuta utilizando el registro como se define en logback-test.xml como de costumbre. Esto se supone para ayudar al escribir / depuración de las pruebas.

2. Se ejecuta con todo el registro habilitado y se graba en un archivo. Este archivo se elimina después de la prueba.

3. Se ejecuta con toda registro desactivado.

Sí, LoggingTestBase necesidades de documentación;)

Otros consejos

¿Ha probado el simple mantenimiento de dos archivos de configuración de registro separado? Cada uno podría conectarse a diferentes niveles, desde el registrador de la raíz.

Todo el registro desactivado

...
<root>
    <priority value="OFF"/>
    <appender-ref ref="LOCAL_CONSOLE"/>
</root>
...

Todo activado el registro

...
<root>
    <priority value="ALL"/>
    <appender-ref ref="LOCAL_CONSOLE"/>
</root>
...

La ejecución sería especificar diferentes configuraciones en la ruta de clase a través de un parámetro del sistema:

-Dlog4j.configuration=path/to/logging-off.xml
-Dlog4j.configuration=path/to/logging-on.xml

Recomendaría cambiar de JUnit a TestNG.TestNG tiene muchas funciones avanzadas sobre JUnit.Le permite ejecutar sus pruebas varias veces con diferentes configuraciones y supongo que eso es lo que necesita.

eqbridges sugerencia de limitarse a ejecutar las pruebas dos veces con diferentes contextos de registro parece la más sencilla. Usted no tiene que acordarse de codificar la lógica en cada prueba bendita, para una gran ventaja. La otra es que usted puede ver qué nivel de registro es el culpable con mucha facilidad.

Una vez dicho esto, hay un par de estrategias si sólo tuviera que hacerlo de una ejecución de prueba.

Para 3.8 Me gustaría poner todo en suites, y hacer dos habitaciones, una para cada nivel de registro, que establece el nivel de registro antes de ejecutar las pruebas. Esto es funcionalmente lo mismo que correr todo el conjunto de pruebas dos veces con diferentes parámetros de línea de comandos, excepto que se obtiene con una carrera.

En JUnit 4.x un par de opciones adicionales vienen a la mente:

Uno es un corredor personalizado. Aunque no se me ocurre fuera de la mano de todo lo que tiene que hacer para hacer este trabajo, pero un corredor que realmente ejecuta la prueba dos veces y anotar la prueba con @RunWith su corredor costumbre podría funcionar.

El otro es pruebas con parámetros. A pesar de que usted realmente tiene que configurar todas las pruebas para tomar parámetros (esto requiere un constructor que toma los argumentos) y luego ponga el nivel de registro de acuerdo con el parámetro.

EDIT: En respuesta a su solicitud de una guía sobre cómo las pruebas paramterized, aquí es el Javadoc en el corredor para empezar, y aquí es una guía más práctica.

Si usted siente que tiene demasiada registro si a su vez en todo, tal vez usted podría tratar de reducir la cantidad de tala. No es muy útil si demasiado para el equipo de procude no importa un ser humano para leer.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top