Software quality assurance days
21 Международная конференция
по вопросам качества ПО
sqadays.com
Москва. 26–27 мая 2017
Соковец Артем
Сбербанк-Технологии, Санкт-Петербург, Россия
Let's Talk About Junit 5
О себе
Артем Соковец
Менеджер направления Research and Development
AVSokovets.SBT@sberbank.ru
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 Release
Q3 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
@BeforeAll
static void beforeAll(){}
@BeforeEach
void beforeEach() {}
@AfterEach
void afterEach() {}
@AfterAll
static void afterAll() {}
@BeforeClass
public static void beforeClass() {}
@Before
public void before() {}
@After
public void after() {}
@AfterClass
public 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
@Test
void ourTest() {
Assertions
.assertTrue(true,
() -> "SQADays");
}
import org.junit.Assert;
import org.junit.Test;
//Code
@Test
public void ourTest() {
Assert
.assertTrue("SQADays",
true);
}
Let's Talk About Junit 5
Junit 5Junit 5 Junit 4Junit 4
import org.junit.Assert;
import org.junit.Test;
//Code
@Test
public 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")
@Test
void test() {
//Code
}
@RunWith(Categories.class)
@IncludeCategory(UnitTests.class)
@SuiteClasses( {TestClass1.class})
public class CategoryTest {}
@Category(UnitTests.class)
@Test
public void test() {
//Code
}
@RunWith(JUnitPlatform.class)
@IncludeTags("work hard")
class TagsTest {}
Let's Talk About Junit 5
Нововведение: #5
Проверка групповых условий
Junit 5Junit 5 Junit 4Junit 4@Rule
public ErrorCollector er =
new ErrorCollector();
@Test
public 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));
}
@Test
void 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>
Вывод при ошибке:
@Test
void test(TestInfo tInfo) {
log.info(tInfo.getDisplayName());
}
Let's Talk About Junit 5
Нововведение: #5
Внедрение параметров в тестовые методы и в
конструкторы тестового класса.
@Rule
public TestName testName
= new TestName();
@Test
public void test() {
log.info(
testName.getMethodName());
}
@Test
void 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.Parameters
public static Collection<Object[]>
data() {return asList(
new Object[][]{{1}});
}
@Test
public 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 очередь")
@TestFactory
Collection<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
}
@Test
void 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 {}
@VideoAndPerfomanceBenchmarks
void ourTest() {…}
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Video
@PerfomanceBenchmarks
@Test
public @interface VideoAndPerfomanceBenchmarks{}
Хочу перезапустить тест, если они упадет по
определенному Exception. Что делать?
Let's Talk About Junit 5
Задача
Использовать интерфейсы Extension Point:
TestTemplateInvocationContextProvider,
AfterTestExecutionCallback
TestTemplateInvocationContext
Let's Talk About Junit 5
Реализация
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@TestTemplate
@ExtendWith(RepeatIfExceptionsCondition.class)
public @interface RepeatedIfExceptionsTest {…}
@Override
public boolean supports(ContainerExtensionContext context) {
return isAnnotated(context.getTestMethod(), RepeatedIfExceptionsTest.class);
}
@Override
public Stream<TestTemplateInvocationContext> provide(ContainerExtensionContext context) {…}
Spliterator<TestTemplateInvocationContext> spliterator =
spliteratorUnknownSize(new TestTemplateIterator(), Spliterator.NONNULL);
@RepeatedIfExceptionsTest(repeats = 5, exceptions = IOException.class
void reRunTest() {…}
@Override
public 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
Вопросы?
Артем Соковец
AVSokovets.SBT@sberbank.ru
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
Спасибо за внимание!

Let's Talk About Junit 5

  • 1.
    Software quality assurancedays 21 Международная конференция по вопросам качества ПО sqadays.com Москва. 26–27 мая 2017 Соковец Артем Сбербанк-Технологии, Санкт-Петербург, Россия
  • 3.
    Let's Talk AboutJunit 5 О себе Артем Соковец Менеджер направления Research and Development AVSokovets.SBT@sberbank.ru
  • 4.
  • 5.
    Let's Talk AboutJunit 5 Содержание  Roadmap  Архитектура  Обзор нововведений  Extension Points  TestNG vs Junit 5  Setup  Top User Questions  Итоги
  • 6.
    Let's Talk AboutJunit 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 Release Q3 2017 Ответственные Johannes Link и Marc Philipp
  • 7.
    Let's Talk AboutJunit 5 Архитектура JUnit 5 = Platform + Jupiter + Vintage Platform Vintage Jupiter Старые тесты Новые тесты Third Party IDEs/Build Tools TestNG, Spock, Cucumber
  • 8.
    Let's Talk AboutJunit 5 Нововведение: #1 Изменились имена аннотаций жизненного цикла Junit 5Junit 5 Junit 4Junit 4 @BeforeAll static void beforeAll(){} @BeforeEach void beforeEach() {} @AfterEach void afterEach() {} @AfterAll static void afterAll() {} @BeforeClass public static void beforeClass() {} @Before public void before() {} @After public void after() {} @AfterClass public static void afterClass () {}
  • 9.
    Let's Talk AboutJunit 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); }
  • 10.
    Let's Talk AboutJunit 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 @Test void ourTest() { Assertions .assertTrue(true, () -> "SQADays"); } import org.junit.Assert; import org.junit.Test; //Code @Test public void ourTest() { Assert .assertTrue("SQADays", true); }
  • 11.
    Let's Talk AboutJunit 5 Junit 5Junit 5 Junit 4Junit 4 import org.junit.Assert; import org.junit.Test; //Code @Test public void ourTest() { Assert .assertTrue("SQADays", true); } Не требуется указывать модификатор видимости public. Изменилось расположение сообщения. Поменялось расположение @Test и assert’ов Нововведение: #3
  • 12.
    Let's Talk AboutJunit 5 Нововведение: #4 Теперь @Category-> @Tag Junit 5Junit 5 Junit 4Junit 4 @Tag("work hard") @Test void test() { //Code } @RunWith(Categories.class) @IncludeCategory(UnitTests.class) @SuiteClasses( {TestClass1.class}) public class CategoryTest {} @Category(UnitTests.class) @Test public void test() { //Code } @RunWith(JUnitPlatform.class) @IncludeTags("work hard") class TagsTest {}
  • 13.
    Let's Talk AboutJunit 5 Нововведение: #5 Проверка групповых условий Junit 5Junit 5 Junit 4Junit 4@Rule public ErrorCollector er = new ErrorCollector(); @Test public 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)); } @Test void groupAssertions() { int[] numbers = {0, 1, 2, 3, 4}; assertAll("numbers", () -> assertEquals(numbers[0], 1), () -> assertEquals(numbers[3], 3), () -> assertEquals(numbers[4], 1)); }
  • 14.
    Let's Talk AboutJunit 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> Вывод при ошибке:
  • 15.
    @Test void test(TestInfo tInfo){ log.info(tInfo.getDisplayName()); } Let's Talk About Junit 5 Нововведение: #5 Внедрение параметров в тестовые методы и в конструкторы тестового класса. @Rule public TestName testName = new TestName(); @Test public void test() { log.info( testName.getMethodName()); } @Test void test1(TestReporter tReport) { tReport.publishEntry ("SQADAYS", “true 100%"); } Junit 5Junit 5 Junit 4Junit 4
  • 16.
    Let's Talk AboutJunit 5 Нововведение: #6 Более детальная информация об исключении
  • 17.
    Let's Talk AboutJunit 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() { /*...*/ } } } Организуемые и легкочитаемые тесты
  • 18.
    Let's Talk AboutJunit 5 Результат выполнения Результаты теста с использованием @Nested и @Display в IDEA
  • 19.
    Let's Talk AboutJunit 5 Нововведение: #8 Обновленные параметризированные возможности @RunWith(value = Parameterized.class) public class HelloTest { //Параметры и конструктор @Parameterized.Parameters public static Collection<Object[]> data() {return asList( new Object[][]{{1}}); } @Test public 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
  • 20.
    Let's Talk AboutJunit 5 Нововведение: #9 Повторяющие и динамические тесты @DisplayName(“Test Method Name") @RepeatedTest(value = 5, name = "{currentRepetition} из {totalRepetitions}") void customDisplayName(TestInfo tInfo, RepetitionInfo rInfo) { repetitionInfo.getCurrentRepetition() repetitionInfo.getTotalRepetitions()); } @DisplayName("Проверка отправки сообщений в mq очередь") @TestFactory Collection<DynamicTest> testDynamicTest() { return Arrays.asList( DynamicTest.dynamicTest("Тест №1", () -> Assertions.assertTrue(true)), DynamicTest.dynamicTest("Тест №2", () -> Assertions.assertFalse(false))); }
  • 21.
    Let's Talk AboutJunit 5 Нововведение: #10 Отдельные методы для работы с timeout Junit 5Junit 5 Junit 4Junit 4 @Test(timeout=1000) public void testWithTimeout() { //Code } @Test void testWithTimeout() { assertTimeout(ofSeconds(5), () -> TimeUnit.SECONDS.sleep(10)); }
  • 22.
    Let's Talk AboutJunit 5 Модель расширений “Prefer extension points over features”“Prefer extension points over features” Основной принцип Junit 5 Extension Points
  • 23.
    Let's Talk AboutJunit 5 Абстрактный пример  Один интерфейс на каждый extension point  Управление контекстом происходит через аргументы метода Использование несколько extension points в реализации public class OurPoint implements ExtensionPoints { // @Override method’s which we need to override! }
  • 24.
    Let's Talk AboutJunit 5 Расширения Test Instance Post Processing Parameter Resolution Conditional Test Execution
  • 25.
    Let's Talk AboutJunit 5 Применения Extension Points @ExtendWith(Clazz.class) Мета-аннотация
  • 26.
    Let's Talk AboutJunit 5 Задача Мы хотим узнать, сколько каждый тест занимает времени. Как это сделать? Использовать интерфейсы Extension Point: BeforeEachCallback, AfterEachCallBack
  • 27.
    Let's Talk AboutJunit 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 }
  • 28.
    Let's Talk AboutJunit 5 Применение через @ExtendWith @ExtendWith(PerfomanceBenchmark.class) public class JUnit5Test { //Тесты  }
  • 29.
    Let's Talk AboutJunit 5 Применение через мета аннотацию @Retention(RetentionPolicy.RUNTIME) @ExtendWith(PerfomanceBenchmark.class) public @interface PerfomanceBenchmarks {} Junit 5 рекурсивно проверяет аннотации у элемента @Test @PerfomanceBenchmarks void ourThirdTest() { assertTrue(true, "DEVDAY СБТ"); }
  • 30.
    Требуется записать видеопрохождения теста. А еще хотелось бы знать время затраченное на каждый тест. Как быть? Let's Talk About Junit 5 Задача Использовать интерфейсы Extension Point: BeforeEachCallback, AfterEachCallBack
  • 31.
    Let's Talk AboutJunit 5 Реализация public class VideoCondition implements BeforeEachCallback, AfterEachCallback { @Override public void beforeEach(TestExtensionContext con) throws Exception { //Получить значение параметра аннотации, начать видеозапись } @Override public void afterEach(TestExtensionContext con) throws Exception { //Остановить видеозапись } }
  • 32.
    Let's Talk AboutJunit 5 Использование @Retention(RetentionPolicy.RUNTIME) @ExtendWith(VideoCondition.class) public @interface Video {} @VideoAndPerfomanceBenchmarks void ourTest() {…} @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @Video @PerfomanceBenchmarks @Test public @interface VideoAndPerfomanceBenchmarks{}
  • 33.
    Хочу перезапустить тест,если они упадет по определенному Exception. Что делать? Let's Talk About Junit 5 Задача Использовать интерфейсы Extension Point: TestTemplateInvocationContextProvider, AfterTestExecutionCallback TestTemplateInvocationContext
  • 34.
    Let's Talk AboutJunit 5 Реализация @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @TestTemplate @ExtendWith(RepeatIfExceptionsCondition.class) public @interface RepeatedIfExceptionsTest {…} @Override public boolean supports(ContainerExtensionContext context) { return isAnnotated(context.getTestMethod(), RepeatedIfExceptionsTest.class); } @Override public Stream<TestTemplateInvocationContext> provide(ContainerExtensionContext context) {…} Spliterator<TestTemplateInvocationContext> spliterator = spliteratorUnknownSize(new TestTemplateIterator(), Spliterator.NONNULL); @RepeatedIfExceptionsTest(repeats = 5, exceptions = IOException.class void reRunTest() {…} @Override public void afterTestExecution(TestExtensionContext context) throws Exception {…}
  • 35.
    Let's Talk AboutJunit 5 Реализация
  • 36.
    Let's Talk AboutJunit 5 TestNG vs Junit 5 slides.com/sergeypirogov/testng-vs-junit-battle#/26
  • 37.
    Let's Talk AboutJunit 5 Setup Maven -> use maven-surefire-plugin Gradle -> Gradle plugin Eclipse -> Eclipse Oxygen 4.7 M7 (Beta) Intellij -> IDEA 2016.2 Console Launcher -> work
  • 38.
    Let's Talk AboutJunit 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
  • 39.
    Let's Talk AboutJunit 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
  • 40.
    Let's Talk AboutJunit 5 Вывод  Использование Java 8;  Много нового функционала;  Один модуль, одна задача;  Гибкое API для построения своего фреймворка.
  • 41.
    Let's Talk AboutJunit 5 Вопросы? Артем Соковец AVSokovets.SBT@sberbank.ru github.com/artsok/Junit5-QADAY goo.gl/zZebHt github.com/sbtqagithub.com/sbtqa goo.gl/wf7Yxi goo.gl/4CB6e1
  • 42.
    Let's Talk AboutJunit 5 Спасибо за внимание!

Editor's Notes

  • #2 Проблемы: Плагин в Idea не понимает файлы с названием $2_FeaturesTest, FeaturesTest1, а в таких файлов могут быть тесты. Плагин в Idea на версии Milistone 3.0, выкидывает ошибку, если тестовый метод называется test
  • #3 Все что я буду говорить и рассказывать основано на моем опыте и на моей точке зрения. За весь код, который будет продемонстрирован сегодня, ответственности не несу)
  • #5 На данном слайде представлена статистика использование junit на проектах github и мы видим, что Junit занимает лидирующую позицию. Сергей Пирогов, так же приводил статистику сравнения, у него выйграл TestNG, но это был какой-то зарубежный сайт. Кто использует этот фреймворк? Поднимите руки. А кто пользуется TestNG? – Вставить в речь!
  • #7 Рассказываю про roadmap Junit 5; Про этапы, которые были и будут; Рассказать, что Marc Philip будет на гейзенбаге и можно послушать его. Будет демонстрировать LiveCoding. Пользователи собрали денег. Нужны были крутые вищи Евро был под 70 руб за одно еуро)
  • #8 К самой сладки вещи перейти. Новая архитектура представляет из себя модульность. Сейчас у нас не большой толстый Jar-ник, который был в предыдущей версии 4, а от отдельные модули отвечающие за свою работу. Jupiter – с помощью данного модуля пишем тесты. Vintage – Запуск тестов версии 5, в версии 4 с помощью @RunWith. Легкая миграция тестов от версии 4 к 5 версии. Platroftm – Служит для запуска и выполнения тестов. Третьи лица, также могут вносить свои реализации тестового движка (через имплементацию junit-platform-engine и регистрацию их движков). Почему назвали Jupiter: Потому-что пятая планета от солнца. Почем назвали Vintage: Чтобы обозначить Legacy. Теперь можно к разработчикам ходить и говорить “Что это за винтажный код”. Слова к данному слайду: JUnit 5 by Marc Philipp - YouTube [720p] (Минута 26:39)
  • #9 Самая кил фича, которая всех убила – это изминение имен анноатций жизненого цикла теста.
  • #10 Дальше еще лучше! Теперь чтобы отключить тест мы используем, другую аннотацию.
  • #11 Кто ответит сколько отличий присутствует между Junit 4 vs Junit 5 тот получит приз? 1) Было:Asserts стало Assertions.assertTrue(); 2) Рассказать, что переехали пакеты! 3) Появилась возможность использовать лямбда выражения; Ленивая инициализация сообщения (т.е подгружаем, когда обращаемся). Принимает Supplier 4) Больше не надо модификатора доступа public – бережем наши пальчики от нажатия на клавиши 
  • #12 Правильно, Изменилось местоположение аннотации @Test Класс Assert изменен на Assertions и поменялось так же его расположение Не требуется модификатора доступа public Изменены расположение параметров в методе AssertTrue Появилось лямбда выражение 1) Было:Asserts стало Assertions.assertTrue(); 2) Рассказать, что переехали пакеты! 3) Появилась возможность использовать лямбда выражения; Ленивая инициализация сообщения (т.е подгружаем, когда обращаемся). Принимает Supplier 4) Больше не надо модификатора доступа public – бережем наши пальчики от нажатия на клавиши 
  • #14 В Junit 4, чтобы реализовать групповые проверки (т.е делаем ассерт и если проверка не прошла то проверяем дальше, то необходимо было использовать правило ErrorCollector). Теперь в Junit 5, больше нету правил – их убрали. Для того чтобы сделать групповую проверку используем метод assertAll, которые принимает варарг проверок.
  • #16 Dependency Injection for Constructors and Methods 1) The TestInfo can then be used to retrieve information about the current test such as the test’s display name, the test class, the test method, or associated tags 2) The TestReporter can be used to publish additional data about the current test run. The data can be consumed through TestExecutionListener.reportingEntryPublished() and thus be viewed by IDEs or included in reports. 3) ParameterResolver defines the API for Extensions that wish to dynamically resolve parameters at runtime.If a constructor for a test class or a @Test, @BeforeEach, @AfterEach, @BeforeAll, or @AfterAll method accepts a parameter, the parameter must be resolved at runtime by a ParameterResolver. Implementations must provide a no-args constructor.
  • #20 Чтобы запускать параметрезированные тесты в 4-ой версии, нам необходимо было указать наш раннер класс (Parameterized.класс), добавить конструктор и дата провайдер с аннотацией @Parameterized.Parameters, который генерил наши данные для тестов. Минус в том, что мы не смогли комбинировать раннеры в месте. В 5-ой версии, механизм работы с параметризованными тестами был доработано. Теперь поддержка параметризованных тестов допускается с помощью аннотаций на методы. Мы должны явно указать что это параметризованный тест и указать конкретный источник по генерации данных. В текущей версии допускается, следующие типы: @ValueSource, @EnumSource, @MethodSource (Два провайдера переберут все значение в каждом провайдере). Дата провайдеры по генерации тестовых данных должны быть static.
  • #22 Чтобы запускать параметрезированные тесты в 4-ой версии, нам необходимо было указать наш раннер класс (Parameterized.класс), добавить конструктор и дата провайдер с аннотацией @Parameterized.Parameters, который генерил наши данные для тестов. Минус в том, что мы не смогли комбинировать раннеры в месте. В 5-ой версии, механизм работы с параметризованными тестами был доработано. Теперь поддержка параметризованных тестов допускается с помощью аннотаций на методы. Мы должны явно указать что это параметризованный тест и указать конкретный источник по генерации данных. В текущей версии допускается, следующие типы: @ValueSource, @EnumSource, @MethodSource (Два провайдера переберут все значение в каждом провайдере). Дата провайдеры по генерации тестовых данных должны быть static.
  • #25 Conditional Test Execution = ContainerExecutionCondition and TestExecutionCondition Test Instance Post Processing = Внедрение зависимостей тестовый инстанс, вовлекая различные кастомные методы в тестовый инстанс
  • #35 Наследуем интерфейсы: TestTemplateInvocationContextProvider и TestTemplateInvocationContextProvider
  • #36 Но как мы знаем что интерфейс: TestTemplateInvocationContext предоставляем метод getDisplayName () для работы с именем теста, то мы можем модифицировать имена.
  • #37 От каких болей Junit избавляет. Рассказать почему Juinit порвет testnG - интерактив
  • #41 Цель сделать наши тесты понятными с минимальным количеством кода
  • #42 Ассерты остались такие же, кроме того что изминилась расположение сообщений. assertThat в Junit 5 больше нет, но если необходимо то можно его подключить из библиотеки org.hamcrest Добавить еще ссылки Дамы и господа, спасибо за внимание. Всем желаю успехов в использовании Junit 5. На этом все. Готов услышать ваши вопросы.