method - junit parameterized
Con jUnit 4, ¿puedo parametrizar @BeforeClass? (5)
Estoy usando jUnit para administrar las pruebas de integración para una aplicación que accede a una base de datos. Debido a que la configuración de los datos de prueba es una operación que requiere mucho tiempo, he estado haciendo eso en el método @BeforeClass
, que se ejecuta solo una vez por clase de prueba (a diferencia del método @Before
, que se ejecuta una vez por método de prueba).
Ahora quiero probar algunas permutaciones diferentes para la configuración de la capa de datos, ejecutando todas mis pruebas en cada configuración diferente. Esto parece ser un uso natural del corredor de prueba Parameterized
. El problema es que Parameterized
suministra parámetros al constructor de la clase, y el método @BeforeClass
es abstracto y se llama antes que el constructor de la clase.
Unas cuantas preguntas,
¿ Parameterized
llama al método @BeforeClass
para cada permutación de parámetros, o solo llama una vez?
Si el método @BeforeClass
se llama repetidamente, ¿hay alguna forma de acceder a los valores de los parámetros desde dentro?
Si nada de esto, ¿qué sugiere la gente como el mejor enfoque alternativo para este problema?
@BeforeClass solo se llama una vez en tu ejemplo. Lo que tiene sentido dado el nombre - antes de la clase!
Si sus pruebas requieren datos diferentes, hay dos opciones que se me ocurren:
- Configure los datos en @Antes para que sean específicos de la prueba.
- Agrupe las pruebas que desea ejecutar con los mismos datos en clases de prueba separadas y use @BeforeClass para cada una.
Creo que vas a necesitar un corredor de prueba personalizado. Tengo el mismo problema que tiene (la necesidad de ejecutar las mismas pruebas utilizando configuraciones múltiples y caras). Necesitaría una forma de parametrizar la configuración, tal vez utilizando @Parameter anotaciones similares a las utilizadas por el corredor parametrizado pero en campos miembro estáticos en lugar de campos de instancia. El corredor personalizado tendría que encontrar todos los campos miembro estáticos con la anotación @Parameter y luego ejecutar la clase de prueba (probablemente usando el BlockJunit4ClassRunner básico) una vez por cada campo estático @Parameter. El campo @Parameter probablemente debería ser un @ClassRule.
Andy on Software ha hecho un buen trabajo en el desarrollo de corredores de prueba personalizados, y lo explica muy claramente en estas publicaciones de blog here y here .
Esta es una pregunta antigua, pero tuve que resolver un problema probablemente similar. Por el momento, opté por la siguiente solución, que básicamente es una implementación de la respuesta (actualizada) de TREE con el uso de una clase base abstracta genérica para evitar la duplicación cada vez que necesite este mecanismo.
Las pruebas concretas proporcionarían un método @Parameters que devuelve un iterable de arreglos de un solo elemento que contienen un Proveedor <T> cada uno. Esos proveedores se ejecutan exactamente una vez por cada entrada real requerida por los métodos de prueba concretos.
@RunWith(Parameterized.class)
public class AbstractBufferedInputTest<T> {
private static Object INPUT_BUFFER;
private static Object PROVIDER_OF_BUFFERED_INPUT;
private T currentInput;
@SuppressWarnings("unchecked")
public AbstractBufferedInputTest(Supplier<T> inputSuppler) {
if (PROVIDER_OF_BUFFERED_INPUT != inputSuppler) {
INPUT_BUFFER = inputSuppler.get();
PROVIDER_OF_BUFFERED_INPUT = inputSuppler;
}
currentInput = (T) INPUT_BUFFER;
}
/**
*
* @return the input to be used by test methods
*/
public T getCurrentInput() {
return currentInput;
}
}
Podría hacer su inicialización en un método @Before, escribiendo en una variable de instancia pero comprobando si es nulo.
@RunWith(value = Parameterized.class)
public class BigThingTests {
private BigThing bigThing;
@Before
public void createBitThing() {
if (bigThing == null) {
bigThing = new BigThing();
}
}
...
}
Se crea una nueva instancia de BigThingTests
para cada conjunto de parámetros, y bigThing
se establece en nulo con cada nueva instancia. El corredor Parameterized
es de un solo hilo, por lo que no tiene que preocuparse por las múltiples inicializaciones.
Puede llamar a esta lógica de inicialización en el constructor de su clase de prueba. Lleve un registro del último parámetro utilizado en una variable estática. Cuando cambie, configure la clase para el nuevo parámetro.
No puedo pensar en un equivalente para AfterClass.