Группировка тестов JUnit - PullRequest
39 голосов
/ 03 мая 2009

Есть ли способ сгруппировать тесты в JUnit, чтобы я мог запускать только некоторые группы?

Или можно аннотировать некоторые тесты и затем глобально отключать их?

Я использую JUnit 4 , я не могу использовать TestNG.

edit: @RunWith и @SuiteClasses отлично работает. Но можно ли так комментировать только некоторые тесты в тестовом классе? Или я должен аннотировать весь тестовый класс?

Ответы [ 7 ]

73 голосов
/ 30 августа 2011

JUnit 4.8 поддерживает группировку:

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

А потом ...

public class AccountTest {

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

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

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

И, наконец,

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

взято отсюда: http://weblogs.java.net/blog/johnsmart/archive/2010/04/25/grouping-tests-using-junit-categories-0

Кроме того, сам Arquillian поддерживает группировку: https://github.com/weld/core/blob/master/tests-arquillian/src/test/java/org/jboss/weld/tests/Categories.java

9 голосов
/ 03 мая 2009

Чтобы справиться с глобальным отключением их, JUnit (4.5+) имеет два способа. Один из них - использовать новый метод acceptThat. Если вы поместите это в @BeforeClass (или @Before) тестового класса, и если условие не выполнится, тест будет проигнорирован. В условии вы можете поместить системное свойство или что-то еще, что можно включить или отключить глобально.

Другой альтернативой является создание пользовательского бегуна, который понимает глобальное свойство и делегирует соответствующему бегуну. Этот подход намного более хрупок (поскольку внутренние бегуны JUnit4 нестабильны и могут меняться от выпуска к выпуску), но он имеет преимущество, заключающееся в возможности наследования по иерархии классов и переопределения в подклассе. Это также единственный реальный способ сделать это, если вам нужно поддерживать устаревшие классы JUnit38.

Вот код для пользовательского Runner. Что касается того, что может сделать getAppresponRunnerForClass, то, как я его реализовал, заключалось в том, чтобы иметь отдельную аннотацию, которая сообщает настраиваемому бегуну, с чем работать. Единственной альтернативой была какая-то очень хрупкая копировальная паста из кода 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);
    }
}

РЕДАКТИРОВАТЬ: тег @RunWith работает только для всего класса. Один из способов обойти это ограничение - переместить тестовые методы в статический внутренний класс и аннотировать его. Таким образом, у вас есть преимущество аннотации с организацией класса. Но это не поможет с тегами @Before или @BeforeClass, вам придется воссоздать их во внутреннем классе. Он может вызывать метод внешнего класса, но он должен иметь свой собственный метод в качестве ловушки.

8 голосов
/ 03 мая 2009

Хотите ли вы сгруппировать тесты внутри тестового класса или вы хотите сгруппировать тестовые классы? Я собираюсь предположить последнее.

Это зависит от того, как вы выполняете свои тесты. Если вы запускаете их в Maven, можно точно указать, какие тесты вы хотите включить. См. документацию Maven верной для этого.

В более общем смысле, однако, я делаю, что у меня есть дерево наборов тестов. Набор тестов в JUnit 4 выглядит примерно так:

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

Итак, может быть, у меня есть FunctionTestsSuite и UnitTestsSuite, а затем AllTestsSuite, который включает в себя два других. Если вы запустите их в Eclipse, вы получите очень хороший иерархический вид.

Проблема этого подхода в том, что он утомителен, если вы хотите разделить тесты несколькими способами. Но это все еще возможно (например, у вас может быть один набор наборов, который будет разделяться на основе модуля, а затем другой набор по типу теста).

3 голосов
/ 12 августа 2018

В JUnit 5 вы можете объявить @Tag для фильтрации тестов на уровне класса или метода; аналогично тестовым группам в TestNG или категориям в JUnit 4

Из Javadoc :

теги используются для фильтрации, какие тесты выполняются для данного теста план. Например, команда разработчиков может пометить тесты такими значениями как «быстрый», «медленный», «ci-сервер» и т. д., а затем предоставить список тегов для использоваться для текущего плана испытаний, потенциально зависит от текущая среда.

Например, вы можете объявить тестовый класс с "slow" @Tag, который будет унаследован для всех методов, и при необходимости переопределить его для некоторых методов:

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(){ 
        ...
   }

}

Вы можете применить ту же логику для других тестовых классов.
Таким образом, тестовые классы (и методы тоже) принадлежат определенному тегу.

В качестве хорошей практики вместо копирования и вставки @Tag("fast") и @Tag("slow") в тестовые классы можно создавать пользовательские составные аннотации.
Например:

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 Slow {
}

и используйте его как:

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

Чтобы включить или отключить тест, помеченный определенным тегом во время выполнения текста, вы можете положиться на документацию maven-surefire-plugin :

Чтобы включить теги или выражения тегов, используйте groups.

Чтобы исключить теги или выражения тегов, используйте excludedGroups.

Просто настройте в вашем pom.xml плагин в соответствии с вашими требованиями (пример документа):

 <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> 

Для справки документация цели теста не обновляется.

3 голосов
/ 24 декабря 2015

Попробуйте Группы тестов JUnit . Из документации:

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

   ...
}
  • Выполнить простую тестовую группу: -Dtestgroup = интеграция
  • Выполнить несколько тестовых групп: -Dtestgroup = group1, group2
  • Выполнить все тестовые группы: -Dtestgroup = all
1 голос
/ 03 мая 2009

Вы можете создать тестовые Suite объекты, содержащие группы тестов. Кроме того, ваша IDE (например, Eclipse) может иметь поддержку для запуска всех тестов, содержащихся в данном пакете.

0 голосов
/ 14 сентября 2016

Вы можете использовать Test Suite (http://qaautomated.blogspot.in/2016/09/junit-test-suits-and-test-execution.html) или категории Junit (http://qaautomated.blogspot.in/2016/09/junit-categories.html)) для эффективной группировки тестовых случаев.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...