Группировка тестов JUnit
-
03-07-2019 - |
Вопрос
Есть ли способ сгруппировать тесты в JUnit, чтобы я мог запускать только некоторые группы?
Или можно аннотировать некоторые тесты, а затем глобально их отключить?
я использую Юнит 4, я не могу использовать TestNG.
редактировать: @RunWith и @SuiteClasses отлично работают.Но можно ли аннотировать таким образом только некоторые тесты в тестовом классе?Или мне нужно аннотировать весь тестовый класс?
Решение
Хотите ли вы сгруппировать тесты внутри тестового класса или вы хотите сгруппировать тестовые классы? Я собираюсь предположить последнее.
Это зависит от того, как вы выполняете свои тесты. Если вы запускаете их в Maven, можно точно указать, какие тесты вы хотите включить. Для этого см. документацию Maven безошибочный . р>
В более общем смысле я использую дерево наборов тестов. Набор тестов в JUnit 4 выглядит примерно так:
@RunWith(Suite.class)
@SuiteClasses(SomeUnitTest1.class, SomeUnitTest2.class)
public class UnitTestsSuite {
}
Итак, может быть, у меня есть FunctionTestsSuite и UnitTestsSuite, а затем AllTestsSuite, который включает в себя два других. Если вы запустите их в Eclipse, вы получите очень хороший иерархический вид.
Проблема этого подхода в том, что он довольно утомителен, если вы хотите разрезать тесты несколькими разными способами. Но это все еще возможно (например, у вас может быть один набор наборов, который будет разделяться на основе модуля, а затем другой набор по типу теста).
Другие советы
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 {}
Взято отсюда: https : //github.com/weld/core/blob/master/tests-arquillian/src/test/java/org/jboss/weld/tests/Categories.java
Чтобы справиться с глобальным их отключением, в 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, вам придется воссоздать их во внутреннем классе. Он может вызывать метод внешнего класса, но он должен иметь собственный метод в качестве ловушки.
Пытаться Тестовые группы JUnit.Из документации:
@TestGroup("integration")
public class MyIntegrationTest {
@ClassRule
public static TestGroupRule rule = new TestGroupRule();
...
}
- Выполните простую группу тестов:-Dtestgroup=интеграция
- Выполнить несколько групп тестов:-Dtestgroup=группа1,группа2
- Выполните все группы тестов:-Dtestgroup=все
В JUnit 5 вы можете объявить @Tag
для фильтрации тестов на уровне класса или метода; аналогично тестовым группам в TestNG или категориям в JUnit 4
Из javadoc :
Тегииспользуются для фильтрации, какие тесты выполняются для данного теста план. Например, команда разработчиков может пометить тесты такими значениями как «быстро», «медленно», «ci-сервер» и т. д., а затем предоставить список тегов для использоваться для текущего плана испытаний, потенциально зависит от текущая среда.
Например, вы можете объявить тестовый класс с " медленным "
@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
.Чтобы исключить теги или выражения тегов, используйте
exclusiveGroups
.
Просто настройте в своем 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>
Для получения информации документация по целям тестирования не обновляется. Р>
Вы можете создать тестовые сюиты , содержащие группы испытаний. Кроме того, ваша IDE (например, Eclipse) может иметь поддержку для запуска всех тестов, содержащихся в данном пакете.
Вы можете использовать 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 ) для эффективной группировки тестовых случаев. р>