Agrupación de pruebas JUnit


¿Hay alguna forma de agrupar pruebas en JUnit, de modo que solo pueda ejecutar algunos grupos?

¿O es posible anotar algunas pruebas y luego deshabilitarlas globalmente?

Estoy usando JUnit 4, no puedo usar TestNG.

Editar: @RunWith y @SuiteClasses funciona muy bien. Pero ¿es posible anotar así solo algunas pruebas en la clase de prueba? ¿O tengo que anotar toda la clase de prueba?

Author: OsipXD, 2009-05-03

7 answers

¿Desea agrupar las pruebas dentro de una clase de prueba o desea agrupar las clases de prueba? Voy a asumir lo último.

Depende de cómo esté ejecutando sus pruebas. Si los ejecuta Maven, es posible especificar exactamente qué pruebas desea incluir. Ver la documentación Maven surefire para esto.

Más generalmente, sin embargo, lo que hago es que tengo un árbol de suites de prueba. Una suite de pruebas en JUnit 4 se ve algo así como:

 @RunWith(Suite.class)
 @SuiteClasses(SomeUnitTest1.class, SomeUnitTest2.class)
 public class UnitTestsSuite {
 }

Así que, tal vez tengo un FunctionTestsSuite y un UnitTestsSuite, y luego un AllTestsSuite que incluye los otros dos. Si los ejecuta en Eclipse obtendrá una vista jerárquica muy agradable.

El problema con este enfoque es que es un poco tedioso si quieres cortar las pruebas en más de una manera diferente. Pero todavía es posible (por ejemplo, puede tener un conjunto de suites que se dividan en función del módulo, luego otro en función del tipo de prueba).

 9
Author: waxwing,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-05-03 14:36:50

JUnit 4.8 soporta agrupación:

public interface SlowTests {}
public interface IntegrationTests extends SlowTests {}
public interface PerformanceTests extends SlowTests {}

Y luego...

public class AccountTest {

    @Test
    @Category(IntegrationTests.class)
    public void thisTestWillTakeSomeTime() {
        ...
    }

    @Test
    @Category(IntegrationTests.class)
    public void thisTestWillTakeEvenLonger() {
        ...
    }

    @Test
    public void thisOneIsRealFast() {
        ...
    }
}

Y por último,

@RunWith(Categories.class)
@ExcludeCategory(SlowTests.class)
@SuiteClasses( { AccountTest.class, ClientTest.class })
public class UnitTestSuite {}

Tomado de aquí: http://weblogs.java.net/blog/johnsmart/archive/2010/04/25/grouping-tests-using-junit-categories-0

Además, Arquillian soporta la agrupación: https://github.com/weld/core/blob/master/tests-arquillian/src/test/java/org/jboss/weld/tests/Categories.java

 73
Author: Ondra Žižka,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-08-29 23:59:40

Para manejar la desactivación global de ellos, JUnit (4.5+) tiene dos maneras, Una es usar el nuevo método assumeThat. Si pones eso en la @BeforeClass (o en la @Before) de una clase test, y si la condición falla, ignorará la prueba. En la condición puede poner una propiedad del sistema u otra cosa que se puede activar o desactivar globalmente.

La otra alternativa es crear un runner personalizado que entienda la propiedad global y delegue en el runner apropiado. Este enfoque es un mucho más frágil (ya que los corredores internos de JUnit4 son inestables y se pueden cambiar de una versión a otra), pero tiene la ventaja de poder heredarse en una jerarquía de clases y ser anulados en una subclase. También es la única forma realista de hacer esto si tienes que soportar clases legacy JUnit38.

Aquí hay un código para hacer el corredor personalizado. En cuanto a lo que getAppropriateRunnerForClass podría hacer, la forma en que lo implementé fue tener una anotación separada que dice la corredor personalizado con qué correr. La única alternativa era un copy paste muy frágil del código JUnit.

private class CustomRunner implements Runner
 private Runner runner;

    public CustomRunner(Class<?> klass, RunnerBuilder builder) throws Throwable {
        if (!isRunCustomTests()) {
            runner = new IgnoredClassRunner(klass);
        } else {
            runner = getAppropriateRunnerForClass(klass, builder);
    }

    public Description getDescription() {
        return runner.getDescription();
    }

    public void run(RunNotifier notifier) {
        runner.run(notifier);
    }
}

EDITAR: La etiqueta @RunWith solo funciona para toda una clase. Una forma de evitar esa limitación es mover los métodos de prueba a una clase interna estática y anotarla. De esta manera usted tiene la ventaja de la anotación con la organización de la clase. Pero, hacer eso no ayudará con ninguna etiqueta @Before o @BeforeClass, tendrás que recrear las de la clase interna. Se puede llamar al método de la clase externa, pero tendría que tener su propio método como un gancho.

 9
Author: Yishai,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-05-05 02:35:29

Intenta Grupos de prueba JUnit. De la documentación:

@TestGroup("integration")
public class MyIntegrationTest {
   @ClassRule
   public static TestGroupRule rule = new TestGroupRule();

   ...
}
  • Ejecute un grupo de prueba simple: - Dtestgroup=integration
  • Ejecutar varios grupos de prueba: - Dtestgroup=group1,group2
  • Ejecutar todos los grupos de prueba: - Dtestgroup=all
 3
Author: Bit-Man,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-12-24 02:23:57

Puede crear objetos test Suite que contengan grupos de pruebas. Alternativamente, su IDE (como Eclipse) puede tener soporte para ejecutar todas las pruebas contenidas en un paquete dado.

 1
Author: Kevin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-05-03 14:25:05

Puede Usar Test Suite ( http://qaautomated.blogspot.in/2016/09/junit-test-suits-and-test-execution.html ) o puede Junit Categorías ( http://qaautomated.blogspot.in/2016/09/junit-categories.html ) para agrupar sus casos de prueba de manera efectiva.

 0
Author: anuja jain,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-09-14 05:24:04

En JUnit 5 se puede declarar @Tag para filtrar pruebas, ya sea a nivel de clase o método; análogo a los grupos de prueba en TestNG o Categorías en JUnit 4

Del javadoc :

Las etiquetas se utilizan para filtrar qué pruebas se ejecutan para una prueba dada plan. Por ejemplo, un equipo de desarrollo puede etiquetar pruebas con valores tales como "rápido", "lento", "ci-server", etc. y luego proporcione una lista de etiquetas a para el plan de prueba actual, potencialmente dependiente de el entorno actual.

Por ejemplo, podría declarar una clase de prueba con una "slow" @Tag que se heredará para todos los métodos y lo anulará para algunos métodos si es necesario :

import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;

@Tag("slow") 
public class FooTest{

   // 
   @Test
   void loadManyThings(){ 
        ...
   }

   @Test
   void loadManyManyThings(){ 
        ...
   }


   @Test
   @Tag("fast")
   void loadFewThings(){ 
        ...
   }

}

Podría aplicar la misma lógica para otras clases de prueba.
De esta manera, las clases de prueba (y los métodos también) pertenecen a una etiqueta específica.

Como una buena práctica en lugar de copiar y pegar @Tag("fast") y @Tag("slow") a lo largo de las clases de prueba, puede crear compuestos personalizados anotaciones.
Por ejemplo :

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import org.junit.jupiter.api.Tag;

@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Tag("slow")
public @interface Fast {
}

Y usarlo como:

@Test
@Slow
void slowProcessing(){ 
    ...
}   

Para habilitar o deshabilitar la prueba marcada con una etiqueta específica durante la ejecución de texto, puede confiar en la documentación maven-surefire-plugin :

Para incluir etiquetas o expresiones de etiquetas, use groups.

Para excluir etiquetas o expresiones de etiquetas, utilice excludedGroups.

Simplemente configure en su pom.xml el plugin de acuerdo a sus necesidades (ejemplo del documento) :

 <build>
     <plugins>
         ...
         <plugin>
             <groupId>org.apache.maven.plugins</groupId>
             <artifactId>maven-surefire-plugin</artifactId>
             <version>2.22.0</version>
             <configuration>
                 <groups>acceptance | !feature-a</groups>
                 <excludedGroups>integration, regression</excludedGroups>
             </configuration>
         </plugin>
     </plugins> 
</build> 

Para información, la documentación test goal no está actualizada.

 0
Author: davidxxx,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-08-12 15:40:06