2010-02-05 20 views
13

Digamos que tengo una clase de prueba llamada testFixtureA con varios métodos, testAtestB, testC, etc, cada uno con @Test anotación.jUnit ignorar los métodos de la clase base @test

Digamos ahora que subclases testFixtureA en la clase llamada testFixtureAB y no sobrescribo nada. testFixtureAB está vacío como por ahora.

Cuando ejecuto pruebas de testFixtureAB, métodos testA, testB y testC son ejecutados por el corredor de prueba debido corredor de prueba no distingue entre los métodos de prueba de clase y clase base.

¿Cómo puedo forzar al corredor de prueba a dejar de lado las pruebas de la clase base?

Respuesta

20

reestructurar sus clases de prueba.

  • Si no desea utilizar las pruebas de la clase base, entonces no extenderlo
  • Si necesita otra funcionalidad de la clase base, dividir la clase en dos - las pruebas, y la otra funcionalidad
+0

Esto no es útil por la razón que @martosoler señala en la respuesta a continuación: hay casos obvios (en mi situación, pruebas de Selenio contra diferentes navegadores) donde este es un muy mal consejo. Usted * quiere * el mismo comportamiento a veces; solo la configuración de su (s) variable (s) "SUT" difiere entre subclases. –

+1

@MikeBurton - En realidad, este es un buen consejo, aunque puede no ser obvio lo que sugiere Bozho. Lo que necesita hacer es * refactorizar * su clase base, extrayendo el código que debe reutilizarse en una nueva clase proto-base (abstracta). Su nueva clase de prueba extendería entonces la clase proto-base en lugar de lo que llamábamos la clase base. Este sería un buen ejemplo de cómo seguir el LSP y la regla general de que nunca se deben anular las implementaciones concretas. Si no le importa romper esas reglas, puede ir con mi recomendación a continuación. –

+0

No sé por qué me oponía a esto en julio. Esta es exactamente la solución con la que finalmente llegué. Aunque en este punto se siente como si hubiera una solución de AOP que resolvería mejor mi problema específico. Sin embargo, no soy lo suficientemente ambicioso como para resolverlo en este momento. –

9

ignorando toda la clase base:

@Ignore 
class BaseClass { 
    // ... 
} 

check out this example

+3

Esto ignorará la clase base en todas partes, por lo que es básicamente inútil. – whiskeysierra

+5

los métodos de prueba heredados se ejecutarán como pruebas en las clases derivadas ... – dfa

+1

¿Hace que la clase base sea abstracta? – user7610

1

en la última JUnit puede utilizar la anotación @Rule en la subclase para inspeccionar el nombre de la prueba y la prueba de funcionamiento interceptar hacer caso omiso de la prueba dinámica. Pero sugeriría que la idea de @ Bozho es la mejor: el hecho de que necesites hacer esto indica un problema mayor que probablemente muestre que la herencia no es la solución correcta aquí.

22

y no sobrescribo nada. testFixtureAB está vacío como por ahora

Ahí tienes tu respuesta. Si desea ejecutar no TESTB de la clase principal, que overrride:

public class testFixtureAB extends testFixtureA { 
    @Override 
    public void testB() {} 
} 
+1

Solución fácil y obvia +1 – whiskeysierra

+1

para aclarar para otros ya que no entendí esta respuesta cuando la vi por primera vez, digamos que tienes el método 'testB' en la clase base anotada con @Test, y no quieres' testB 'prueba para ejecutar en su subclase, luego vaya a la subclase, anule este método' testB', entonces esta prueba ya no se ejecutará en su subclase –

1

lo sé, no es la respuesta ...

en cuenta la razón por la cual se amplía clases de prueba de hormigón. Usted duplica los métodos de prueba de esa manera.

Si comparte código entre pruebas, entonces considere escribir clases de prueba base con helper and fixture setup methods o test helper class.

Si para ejecutar pruebas intente organizar pruebas con suites y categories.

1

¿Qué sucede si desea ejecutar la misma prueba para diferentes configuraciones del mismo banco de pruebas?

Por ejemplo, supongamos que tiene Clase A con métodos test1, test2 y test3 que llegan a una base de datos incrustada y luego desea crear "setUp" y "tearDown" separados para cada proveedor integrado (H2, HyperSQL, etc.) pero ejecuta las mismas pruebas para cada uno.

Me gustaría extender una clase que contenga esos métodos de prueba y configurarlo en una subclase. Mi problema es que la súper clase NO DEBE considerarse elegible para el corredor de prueba. El problema surge cuando el corredor de prueba ejecuta la superclase y dado que no se encontraron los métodos de montaje y desmontaje correspondientes, que crashs :(

6

Es muy fácil de lograr la aplicación de algunas pocas clases:

  • Crear su propio TestRunner
  • Crear una anotación como @IgnoreInheritedTests
  • Crear una clase que se extiende org.junit.runner.manipulation.Filter

En la clase de filtro:

public class InheritedTestsFilter extends Filter { 

    @Override 
    public boolean shouldRun(Description description) { 
     Class<?> clazz = description.getTestClass(); 
     String methodName = description.getMethodName(); 
     if (clazz.isAnnotationPresent(IgnoreInheritedTests.class)) { 
      try { 
       return clazz.getDeclaredMethod(methodName) != null; 
      } catch (Exception e) { 
       return false; 
      } 
     } 
     return true; 
    } 

    @Override 
    public String describe() { 
     // TODO Auto-generated method stub 
     return null; 
    } 

} 

en su corredor de encargo:

/** 
* @param klass 
* @throws InitializationError 
* @since 
*/ 
public CustomBaseRunner(Class<?> klass) throws InitializationError { 
    super(klass); 
    try { 
     this.filter(new InheritedTestsFilter()); 
    } catch (NoTestsRemainException e) { 
     throw new IllegalStateException("class should contain at least one runnable test", e); 
    } 
} 
0

En la clase de prueba de base métodos @test:

assumeTrue(getClass().equals(BaseClassTest.class)); 

ignorará los de las pruebas de subclases pero no los deja completamente afuera.

Cuestiones relacionadas