42
Software quality assurance days 21 Международная конференция по вопросам качества ПО sqadays.com Москва. 26–27 мая 2017 Соковец Артем Сбербанк-Технологии, Санкт-Петербург, Россия

Let's Talk About Junit 5

  • Upload
    sqalab

  • View
    490

  • Download
    3

Embed Size (px)

Citation preview

Software quality assurance days

21 Международная конференция по вопросам качества ПОsqadays.com

Москва. 26–27 мая 2017

Соковец АртемСбербанк-Технологии, Санкт-Петербург, Россия

Let's Talk About Junit 5

О себеАртем Соковец Менеджер направления Research and Development

[email protected]

http://blog.takipi.com/we-analyzed-60678-libraries-on-github-here-are-the-top-100/

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

Нововведение: #6

Более детальная информация об исключении

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 Points

@ExtendWith(Clazz.class)

Мета-аннотация

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

Реализация

Let's Talk About Junit 5

TestNG vs Junit 5

slides.com/sergeypirogov/testng-vs-junit-battle#/26

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

Let's Talk About Junit 5

Спасибо за внимание!