Download - Let's Talk About Junit 5
Software quality assurance days
21 Международная конференция по вопросам качества ПОsqadays.com
Москва. 26–27 мая 2017
Соковец АртемСбербанк-Технологии, Санкт-Петербург, Россия
Let's Talk About Junit 5
О себеАртем Соковец Менеджер направления Research and Development
Let's Talk About Junit 5
Содержание
Roadmap
Архитектура
Обзор нововведений
Extension Points
TestNG vs Junit 5
Setup
Top User Questions
Итоги
Let's Talk About Junit 5
RoadMap Junit 5
Phase 0: Crowdfunding Campaign
Phase 1: Kickoff Meeting -> 22.10.2015
Phase 2: The Prototype -> 02.12.2015
Phase 3: Heading for an Alpha -> 01.02.2016
Phase 4: Working Toward a First Milestone -> 07.07.2016
Phase 5: Additional Milestones -> (M4) 01.04.2017
Phase 6: Release Candidates
Phase 7: GA ReleaseQ3 2017
ОтветственныеJohannes Link и
Marc Philipp
Let's Talk About Junit 5
АрхитектураJUnit 5 = Platform + Jupiter + Vintage
Platform
Vintage Jupiter
Старые тесты
Новыетесты
Third Party
IDEs/Build Tools
TestNG, Spock,
Cucumber
Let's Talk About Junit 5
Нововведение: #1
Изменились имена аннотаций жизненного цикла
Junit 5Junit 5 Junit 4Junit 4
@BeforeAllstatic void beforeAll(){}
@BeforeEachvoid beforeEach() {}
@AfterEachvoid afterEach() {}
@AfterAllstatic void afterAll() {}
@BeforeClasspublic static void beforeClass() {}
@Beforepublic void before() {}
@Afterpublic void after() {}
@AfterClasspublic static void afterClass () {}
Let's Talk About Junit 5
Нововведение: #2
Теперь @Ignore -> @Disabled
Junit 5Junit 5 Junit 4Junit 4
@Test@Disabled(“No Run")void test() { assertTrue(false,"SQADAYS");}
@Test@Ignore(“No Run")public void test() { assertTrue("SQADAYS“, false);}
Let's Talk About Junit 5
Junit 5Junit 5 Junit 4Junit 4
Сколько отличий между Junit 5 vs Junit 4?
import org.junit.jupiter.api.Assertions;import org.junit.jupiter.api.Test;
//Code@Testvoid ourTest() {
Assertions.assertTrue(true,
() -> "SQADays");}
import org.junit.Assert;import org.junit.Test;
//Code@Testpublic void ourTest() {
Assert.assertTrue("SQADays",
true);}
Let's Talk About Junit 5
Junit 5Junit 5 Junit 4Junit 4import org.junit.Assert;import org.junit.Test;
//Code@Testpublic void ourTest() {
Assert.assertTrue("SQADays",
true);}
Не требуется указывать модификатор видимости public. Изменилось расположение сообщения.Поменялось расположение @Test и assert’ов
Нововведение: #3
Let's Talk About Junit 5
Нововведение: #4
Теперь @Category-> @Tag
Junit 5Junit 5 Junit 4Junit 4
@Tag("work hard")@Testvoid test() {
//Code}
@RunWith(Categories.class)@IncludeCategory(UnitTests.class)@SuiteClasses( {TestClass1.class})public class CategoryTest {}
@Category(UnitTests.class)@Testpublic void test() {
//Code}
@RunWith(JUnitPlatform.class)@IncludeTags("work hard")class TagsTest {}
Let's Talk About Junit 5
Нововведение: #5
Проверка групповых условий
Junit 5Junit 5 Junit 4Junit 4@Rulepublic ErrorCollector er =
new ErrorCollector();
@Testpublic void groupassert() { int[] numbers = {0, 1, 2, 3, 4}; er.checkThat(numbers[0], is(1)); er.checkThat(numbers[3], is(3)); er.checkThat(numbers[4], is(1));}
@Testvoid groupAssertions() {int[] numbers = {0, 1, 2, 3, 4};assertAll("numbers", () -> assertEquals(numbers[0], 1), () -> assertEquals(numbers[3], 3), () -> assertEquals(numbers[4], 1));}
Let's Talk About Junit 5
Результат выполнения
org.opentest4j.MultipleFailuresError: numbers (2 failures)expected: <0> but was: <1>expected: <4> but was: <1>
org.opentest4j.MultipleFailuresError: numbers (2 failures)expected: <0> but was: <1>expected: <4> but was: <1>
Вывод при ошибке:
@Testvoid test(TestInfo tInfo) { log.info(tInfo.getDisplayName());}
Let's Talk About Junit 5
Нововведение: #5
Внедрение параметров в тестовые методы и в конструкторы тестового класса.
@Rulepublic TestName testName
= new TestName();
@Testpublic void test() { log.info(
testName.getMethodName());}
@Testvoid test1(TestReporter tReport) { tReport.publishEntry
("SQADAYS", “true 100%");}
Junit 5Junit 5 Junit 4Junit 4
Let's Talk About Junit 5
Нововведение: #7 @DisplayName("СББОЛ TK API - Отправка писем в банк")public class BDDStyleTest { @Test @DisplayName("Дано пользователь авторизовался в систему") void login() { /*...*/ }
@Test @DisplayName("Когда пользователь отправляет сообщение") void sendMess() { /*...*/ }
@Nested @DisplayName("Тогда система присылает ответ") class AfterSending { @Test @DisplayName("идентификатор уникальный") void checkTicket() { /*...*/ } @Test @DisplayName("идентификатор заполнен корректно") void checkTicketField() { /*...*/ } }}
Организуемые и легкочитаемые тесты
Let's Talk About Junit 5
Результат выполнения
Результаты теста с использованием @Nested и @Display в IDEA
Let's Talk About Junit 5
Нововведение: #8
Обновленные параметризированные возможности
@RunWith(value = Parameterized.class)public class HelloTest {//Параметры и конструктор @Parameterized.Parameterspublic static Collection<Object[]>
data() {return asList(new Object[][]{{1}});
}
@Testpublic void compareTest() { assertTrue(numberA > 0);}}
@ParameterizedTest@ValueSource(ints = {1, 2, 3})void valueSource(int arg) { assertTrue(arg > 0);}
Junit 5Junit 5 Junit 4Junit 4
@ParameterizedTest@MethodSource(names = "dProvider")void methodSource(String arg) { assertNotNull(arg);}
@ParameterizedTest@CsvFileSource(resources =“.csv")//Code
@ParameterizedTest@ArgumentsSource(Provider.class)//Code
Let's Talk About Junit 5
Нововведение: #9
Повторяющие и динамические тесты
@DisplayName(“Test Method Name")@RepeatedTest(value = 5, name = "{currentRepetition} из {totalRepetitions}")void customDisplayName(TestInfo tInfo, RepetitionInfo rInfo) {
repetitionInfo.getCurrentRepetition()repetitionInfo.getTotalRepetitions());
}
@DisplayName("Проверка отправки сообщений в mq очередь")@TestFactoryCollection<DynamicTest> testDynamicTest() { return Arrays.asList( DynamicTest.dynamicTest("Тест №1", () -> Assertions.assertTrue(true)), DynamicTest.dynamicTest("Тест №2", () -> Assertions.assertFalse(false)));}
Let's Talk About Junit 5
Нововведение: #10
Отдельные методы для работы с timeout
Junit 5Junit 5 Junit 4Junit 4
@Test(timeout=1000)public void testWithTimeout() { //Code}
@Testvoid testWithTimeout() {
assertTimeout(ofSeconds(5), () -> TimeUnit.SECONDS.sleep(10));}
Let's Talk About Junit 5
Модель расширений
“Prefer extension points over features”“Prefer extension points over features”
Основной принцип Junit 5
Extension Points
Let's Talk About Junit 5
Абстрактный пример
Один интерфейс на каждый extension point
Управление контекстом происходит через аргументы метода
Использование несколько extension points в реализации
public class OurPoint implements ExtensionPoints { // @Override method’s which we need to override!}
Let's Talk About Junit 5
Расширения
Test Instance Post Processing
Parameter Resolution
Conditional Test Execution
Let's Talk About Junit 5
Задача
Мы хотим узнать, сколько каждый тест занимает времени. Как это сделать?
Использовать интерфейсы Extension Point: BeforeEachCallback, AfterEachCallBack
Let's Talk About Junit 5
Реализация
public class PerfomanceBenchmark implements BeforeEachCallback, AfterEachCallback {
@Override public void afterEach(TestExtensionContext con) throws Exception {
//Code }
@Override public void beforeEach(TestExtensionContext con) throws Exception {
//Code }
Let's Talk About Junit 5
Применение через @ExtendWith
@ExtendWith(PerfomanceBenchmark.class)public class JUnit5Test {
//Тесты }
Let's Talk About Junit 5
Применение через мета аннотацию
@Retention(RetentionPolicy.RUNTIME)@ExtendWith(PerfomanceBenchmark.class)public @interface PerfomanceBenchmarks {}
Junit 5 рекурсивно проверяет аннотации у элемента
@Test@PerfomanceBenchmarks void ourThirdTest() { assertTrue(true, "DEVDAY СБТ");}
Требуется записать видео прохождения теста. А еще хотелось бы знать время затраченное
на каждый тест. Как быть?
Let's Talk About Junit 5
Задача
Использовать интерфейсы Extension Point: BeforeEachCallback, AfterEachCallBack
Let's Talk About Junit 5
Реализация
public class VideoCondition implements BeforeEachCallback, AfterEachCallback {
@Override public void beforeEach(TestExtensionContext con) throws Exception {
//Получить значение параметра аннотации, начать видеозапись } @Override public void afterEach(TestExtensionContext con) throws Exception {
//Остановить видеозапись }}
Let's Talk About Junit 5
Использование
@Retention(RetentionPolicy.RUNTIME)@ExtendWith(VideoCondition.class)public @interface Video {}
@VideoAndPerfomanceBenchmarksvoid ourTest() {…}
@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)@Video@PerfomanceBenchmarks@Testpublic @interface VideoAndPerfomanceBenchmarks{}
Хочу перезапустить тест, если они упадет по определенному Exception. Что делать?
Let's Talk About Junit 5
Задача
Использовать интерфейсы Extension Point:TestTemplateInvocationContextProvider,
AfterTestExecutionCallbackTestTemplateInvocationContext
Let's Talk About Junit 5
Реализация
@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)@TestTemplate@ExtendWith(RepeatIfExceptionsCondition.class)public @interface RepeatedIfExceptionsTest {…}
@Overridepublic boolean supports(ContainerExtensionContext context) { return isAnnotated(context.getTestMethod(), RepeatedIfExceptionsTest.class);}
@Overridepublic Stream<TestTemplateInvocationContext> provide(ContainerExtensionContext context) {…}
Spliterator<TestTemplateInvocationContext> spliterator = spliteratorUnknownSize(new TestTemplateIterator(), Spliterator.NONNULL);
@RepeatedIfExceptionsTest(repeats = 5, exceptions = IOException.classvoid reRunTest() {…}
@Overridepublic void afterTestExecution(TestExtensionContext context) throws Exception {…}
Let's Talk About Junit 5
Setup
Maven -> use maven-surefire-plugin
Gradle -> Gradle plugin
Eclipse -> Eclipse Oxygen 4.7 M7 (Beta)
Intellij -> IDEA 2016.2
Console Launcher -> work
Let's Talk About Junit 5
Setup
<dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter-api</artifactId> <version>5.0.0-M3</version> <scope>compile</scope></dependency>
<build> <plugins> <plugin> <artifactId>maven-surefire-plugin</artifactId> <version>2.19</version> <dependencies> <dependency> <groupId>org.junit.platform</groupId> <artifactId>junit-platform-surefire-provider</artifactId> <version>${junit.platform.version}</version> </dependency> </dependencies> </plugin> </plugins></build>
Maven
Let's Talk About Junit 5
Top questions
1. Difference between @Before, @BeforeClass, @BeforeEach and @BeforeAll
2. Surefire is not picking up Junit 5 tests
3. Как запускать тесты, когда IDE не поддерживает Junit 5
4. Пропал метод asertThat()
5. Интеграция с Allure 2.0/Allure
Let's Talk About Junit 5
Вывод
Использование Java 8;
Много нового функционала;
Один модуль, одна задача;
Гибкое API для построения своего фреймворка.
Let's Talk About Junit 5
Вопросы?Артем Соковец [email protected]
github.com/artsok/Junit5-QADAY
goo.gl/zZebHt
github.com/sbtqagithub.com/sbtqa
goo.gl/wf7Yxi goo.gl/4CB6e1