junit - name - meta tags
¿Cómo adjuntar un DataPoint con una teoría? (4)
@DataPoints public static final Integer[] input1={1,2};
@Theory
@Test
public void test1(int input1){
}
@DataPoints public static final Integer[] input2={3,4};
@Theory
@Test
public void test2(int input2 ){
}
Quiero que test1 se ejecute con el conjunto de datos input1 - {1,2} y test2 se ejecute con input2 - {3,4}. Pero actualmente, cada prueba se ejecuta con ambos conjuntos de datos {1,2,3,4}. Cómo enlazar @DataPoints específicos a @Theorys específicos
Algunas de las referencias que he visto hablan sobre el uso de pruebas para valores específicos y teorías para verificar el comportamiento. Como ejemplo, si tiene una clase que tiene métodos para sumar y restar de un atributo, una prueba verificará la corrección del resultado (por ejemplo, 1 + 3 devuelve 4) mientras que una teoría podría verificar que, para los valores de punto de datos (x1 , y1), (x2, y2), x + yy siempre es igual a x, x-y + y siempre es igual a x, x * y / y siempre es igual a x, etc. De esta manera, los resultados de las teorías no se relacionan tan estrechamente con los datos. Con las teorías, también puede filtrar casos como y == 0; no cuentan como fracaso En pocas palabras: puede utilizar ambos. Un buen artículo es: http://web.archive.org/web/20110608210825/http://shareandenjoy.saff.net/tdd-specifications.pdf
Con JUnit 4.12 (no estoy seguro de cuándo se introdujo) es posible nombrar los DataPoints y asignarlos a parámetros (lo aprendí de http://farenda.com/junit/junit-theories-with-datapoints/ ):
@RunWith(Theories.class)
public class TheoriesAndDataPointsTest {
@DataPoints("a values")
public static int[] aValues() {
return new int[]{1, 2};
}
@DataPoints("b values")
public static int[] bValues() {
return new int[]{3, 4};
}
@Theory
public void theoryForA(@FromDataPoints("a values") int a) {
System.out.printf("TheoryForA called with a = %d/n", a);
}
@Theory
public void theoryForB(@FromDataPoints("b values") int a) {
System.out.printf("TheoryForB called with b = %d/n", a);
}
}
Salida:
TheoryForA called with a = 1
TheoryForA called with a = 2
TheoryForB called with b = 3
TheoryForB called with b = 4
En referencia a la respuesta de Gábor Lipták , los puntos de datos con nombre se pueden definir como campos estáticos ( reference ) que nos dan un código más conciso:
@RunWith(Theories.class)
public class TheoriesAndDataPointsTest {
@DataPoints("a values")
public static int[] aValues = {1, 2};
@DataPoints("b values")
public static int[] bValues = {3, 4};
@Theory
public void theoryForA(@FromDataPoints("a values") int a) {
System.out.printf("TheoryForA called with a = %d/n", a);
}
@Theory
public void theoryForB(@FromDataPoints("b values") int a) {
System.out.printf("TheoryForB called with b = %d/n", a);
}
}
Los puntos de datos se aplican a la clase. Si tiene un método @Theory que toma un int, y tiene un DataPoint que es una matriz de entradas, se llamará con el int.
@RunWith(Theories.class)
public class TheoryTest {
@DataPoint public static int input1 = 45;
@DataPoint public static int input2 = 46;
@DataPoints public static String[] inputs = new String[] { "foobar", "barbar" };
@Theory public void testString1(String input) {
System.out.println("testString1 input=" + input);
}
@Theory public void testString2(String input) {
System.out.println("testString2 input=" + input);
}
@Theory public void test1(int input) {
System.out.println("test1 input=" + input);
}
@Theory public void test2(int input) {
System.out.println("test2 input=" + input);
}
}
Esto llama test1 con 45 y 46, y test2 con 45 y 46. Llama testString1 con "foobar" y "barbar" y testString2 con "foobar" y "barbar".
Si realmente desea utilizar diferentes conjuntos de datos para diferentes teorías, puede ajustar los datos en una clase privada:
@RunWith(Theories.class)
public class TheoryTest {
public static class I1 { int i; public I1(int i) { this.i = i;} }
public static class I2 { int i; public I2(int i) { this.i = i;} }
@DataPoint public static I1 input1 = new I1(45);
@DataPoint public static I2 input2 = new I2(46);
@Theory
public void test1(I1 input) {
System.out.println("test1 input=" + input.i);
}
@Theory
public void test2(I2 input) {
System.out.println("test2 input=" + input.i);
}
}
Esto llama prueba1 con 45 y prueba2 con 46. Esto funciona, pero en mi opinión, oculta el código, y puede ser una mejor solución simplemente para dividir la clase Prueba en dos clases.