t.me/atinfo_chat Telegram группа по автоматизации тестирования

Не запускаются параметризированные тесты в Nested

java
webdriver
junit
selenium
maven
junit5
Теги: #<Tag:0x00007f21e4cb6b48> #<Tag:0x00007f21e4cb6a08> #<Tag:0x00007f21e4cb6878> #<Tag:0x00007f21e4cb6738> #<Tag:0x00007f21e4cb6558> #<Tag:0x00007f21e4cb6418>

(Pavel) #1

Всем привет!

Разделил тесты на Nested, так удобнее аннотировать для отчётов. Но столкнулся с такой проблемой, что параметрические тесты не запускаются, когда класс. Отдельно запускаются и отрабатывают.

package ru.minicom.itphone.client;

import io.qameta.allure.*;

import org.junit.jupiter.api.*;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import org.junit.jupiter.api.TestMethodOrder;
import org.junit.jupiter.api.Order;
import org.junit.runners.Parameterized;

import java.util.ArrayList;

import static junit.framework.Assert.assertTrue;

@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
@Epic(value = "Тестирование окна логина")
@Feature(value = "Тетирование авторизации с некооректными данными")
@ExtendWith(StartingTest.class)
public class test_1_WindowLogin {

    private static boolean window;

    private static WindowLogin windowLogin  = new WindowLogin(new StartTest().startClient());

    //@Feature(value = "Тетирование авторизации с некооректными данными")
    @Story(value = "Авторизации на сервере, когда поле сервер не заполнено")
    @Description("Тестирование авторизации на сервере, когда поле сервер не заполнено")
    @DisplayName("Поле сервер не заполнено...")
    @Test
    @Order(1)
    void testNoEnterServer() {
        windowLogin.setDataFields("2002", "jkakdjahjdasj");
        windowLogin.clickEnterButton();
        window = windowLogin.isAvailablekWindowEmptyServer();
        windowLogin.clickButtonWindowEmptyServer();
        assertTrue(window);
    }

    //@Feature(value = "Тетирование авторизации с некооректными данными")
    @Story(value = "Авторизации на сервере с некорректным логином и корректным паролем")
    @Description("Авторизации на сервере с некорректным логином и корректным паролем")
    @DisplayName("Проверка на некорректный логин...")
    @Test
    @Order(2)
    void testWrongLogin() {
        windowLogin.setDataFields("ahdasda", "o0cJ2uas", "172.22.50.100");
        windowLogin.clickEnterButton();
        window = windowLogin.isAvailablekWindowWithInvalidCreds();
        windowLogin.clickButtonWindowInvalidCreds();
        assertTrue(window);
    }

    //@Feature(value = "Тетирование авторизации с некооректными данными")
    @Story(value = "Тестирование авторизации на сервере с корректным логином и некорректным паролем")
    @Description("Тестирование авторизации на сервере с корректным логином и некорректным паролем")
    @DisplayName("Проверка на некорректный пароль...")
    @Order(3)
    @Test
    void testWrongPassword() {
        windowLogin.setDataFields("2002", "jkakdjahjdasj", "172.22.50.100");
        windowLogin.clickEnterButton();
        window = windowLogin.isAvailablekWindowWithInvalidCreds();
        windowLogin.clickButtonWindowInvalidCreds();
        assertTrue(window);
    }

    //@Feature(value = "Тетирование авторизации с некооректными данными")
    @Story(value = "Авторизации на сервере с некорректным адресом сервера")
    @Description("Авторизации на сервере с некорректным адресом сервера")
    @DisplayName("Введён некорректный сервер...")
    @Order(4)
    @Test
    void testInvalidServer() {
        windowLogin.setDataFields("2002", "o0cJ2uas", "1");
        windowLogin.clickEnterButton();
        window = windowLogin.isAvailableWindowInvalidServer();
        windowLogin.clickButtonWindowInwalidServer();
        assertTrue(window);
    }

    @Nested
    @ExtendWith(StartingTest.class)
    @Epic(value = "Тестирование окна логина")
    @Feature(value = "Тестирование разных окон")
    class TestsDifferentWindows{

        //@Feature(value = "Тестирование разных окон")
        @Story(value = "Тестирование отмены подтверждения выхода из программы")
        @Description("Отмена подтверждения выхода из программы")
        @DisplayName("Отмена подтверждения выхода из программы...")
        @Test
        void testNotExitAuthWindow() {
            windowLogin.clickNoExitConfirmForm();
            window = windowLogin.isAvailableLoginWindow();
            assertTrue(window);
        }

        //@Feature(value = "Тестирование разных окон")
        @Story(value = "Тестирование окна поиска сервера")
        @Description("Тестирование окна поиска сервера")
        @DisplayName("Проверка окна поиска сервера...")
        @Test
        void testWindowLookServers() {
            windowLogin.clickButtonLookServers();
            window = windowLogin.isAvailableWindowLookServers();
            windowLogin.clickButtonExitWindowLookServers();
            assertTrue(window);
        }
    }


    @Nested
    @ExtendWith(StartingTest.class)
    @Epic(value = "Тестирование окна логина")
    @Feature(value = "Параметрические тесты")
    class TestsParameters{

        private static final String str = "!\"#$%&";

        @Parameterized.Parameters(name = "{0}")
        public Iterable<Character> Symbols(){
            ArrayList<Character> data = new ArrayList<>();

            for (char c : str.toCharArray()) data.add(c);

            return data;
        }

        @Parameterized.Parameters(name = "{0}")
        public Iterable<String> Text(){
            ArrayList<String> data = new ArrayList<>();
            String tempStr = "";

            for (char c : str.toCharArray()){
                tempStr = tempStr + c;
                data.add(tempStr);
            }

            return data;
        }

        @Story(value = "Тестирование ввода любых символов в поле логин")
        @DisplayName("Тест на ввод символов в поле логина...")
        @Description("Тестирование ввода любых символов в поле логин")
        @ParameterizedTest
        @MethodSource("Symbols")
        void testSymbolsLogin(char symbol){
            windowLogin.setLogin(Character.toString(symbol));
            System.out.println("Login: " + windowLogin.getLogin());
            char[] rez = windowLogin.getLogin().toCharArray();
            assertTrue(symbol == rez[0]);
        }

        @Story(value = "Тестирование ввода любых символов в поле сервер")
        @DisplayName("Тест на ввод символов в поле логина...")
        @Description("Тестирование ввода любых символов в поле сервер")
        @ParameterizedTest
        @MethodSource("Symbols")
        void testSymbolsServer(char symbol){
            windowLogin.setServer(Character.toString(symbol));
            System.out.println("Server: " + windowLogin.getServer());
            char[] rez = windowLogin.getServer().toCharArray();
            assertTrue(symbol == rez[0]);
        }

        @Story(value = "Тестирование возможности ввода логина любой длины до 32 символов")
        @DisplayName("Тест на длину логина разной длины до 32 символов...")
        @Description("Тестирование возможности ввода логина любой длины до 32 символов")
        @ParameterizedTest
        @MethodSource("Text")
        void testLengthLogin(String text){
            windowLogin.setLogin(text);
            String tmpStr = windowLogin.getLogin();
            assertTrue(! tmpStr.isEmpty() && tmpStr.length() <= 32);
        }
    }


    @Nested
    @ExtendWith(StartingTest.class)
    @Epic(value = "Тестирование окна логина")
    @Feature(value = "Тестирование пустых полей")
    class TestsEmptyField{

        @Story(value = "Поле логина не заполнено")
        @Description("Если поле логина пустое, кнопка Войти должна быть неактивной")
        @DisplayName("Поле сервер не заполнено...")
        @Test
        void testEmptyFieldLogin() {
            windowLogin.clearLogin();
            windowLogin.setPassword("o0cJ2uas");
            windowLogin.setServer("172.22.50.100");
            assertTrue("Кнопка войти активна!", windowLogin.isInactiveButtonEnter().equals("False"));
        }

        @Story(value = "Поле пароль не заполнено")
        @Description("Если поле пароль пустое, кнопка Войти должна быть неактивной")
        @DisplayName("Поле пароль не заполнено...")
        @Test
        void testEmptyFieldPassword() {
            windowLogin.setLogin("2002");
            windowLogin.clearPassword();
            windowLogin.setServer("172.22.50.100");
            assertTrue("Кнопка войти активна!", windowLogin.isInactiveButtonEnter().equals("False"));
        }

        @Story(value = "Поле сервер не заполнено")
        @Description("Если поле сервер пустое, кнопка Войти должна быть неактивной")
        @DisplayName("Поле сервер не заполнено...")
        @Test
        void testEmptyFieldServer() {
            windowLogin.setLogin("2002");
            windowLogin.setPassword("o0cJ2uas");
            windowLogin.setServer("");
            window = windowLogin.isAvailablekWindowEmptyServer();
            windowLogin.clickButtonWindowEmptyServer();
            assertTrue(window);
            //assertTrue("Кнопка войти активна!", windowLogin.isInactiveButtonEnter().equals("False"));
        }
    }
}

(Михаил Братухин) #2

https://github.com/junit-team/junit5/issues/1229

Using @TestInstance(PER_CLASS) changes the default behavior.

(Михаил Братухин) #3

Ещё раз глянул на ваш код уже с компьютера, а не телефона. Там проблема у вас с объявлением параметризации. Вы используете JUnit4 нотацию, а нужно использовать JUnit5 вариант. Плюс для @Nested классов нельзя использовать статику (внутри самого класса) и поэтому нужно либо вовне искать метод или на классах вешать аннотацию @TestInstance (TestInstance.Lifecycle.PER_CLASS)

Подробности все в оф. документации:
https://junit.org/junit5/docs/current/user-guide/#writing-tests-parameterized-tests-sources-MethodSource

При этом @Parameterized.Parameters(name = "{0}") по сути ни на что не влияет. Работает с ним точно также, просто он игнорируется.

Накидал простой пример, где все работает:

package com.github.bratuhin.example;

import org.junit.jupiter.api.*;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import org.junit.jupiter.params.provider.ValueSource;
import org.junit.runners.Parameterized;

import java.util.ArrayList;
import java.util.stream.Stream;

public class JupiterTest {
  @Test
  @Tag(value = "One")
  @Tag(value = "Jupiter")
  void test1() {
    System.out.println("This is Jupiter test1!");
  }

  @Test
  @Tag(value = "Two")
  @Tag(value = "Jupiter")
  void test2() {
    System.out.println("This is Jupiter test2!");
  }

  @Nested
  @DisplayName("Nested non parametrized")
  class NonParamsTest {
    @Test
    void testNested() {
      System.out.println("This is Nested test!");
    }
  }

  @Nested
  @TestInstance(TestInstance.Lifecycle.PER_CLASS)
  @DisplayName("Nested parametrized")
  class ParamsTest {

    @ParameterizedTest
    @DisplayName("Test params {}")
    @ValueSource(ints = {1, 2, 3, 4, 5})
    void testNestedParams(Integer value) {
      System.out.println("This is Nested test! Params = " + value);
    }

    Stream<String> getValue() {
      return Stream.of("apple", "banana");
    }

    @ParameterizedTest
    @MethodSource("getValue")
    void testNesteParamsWithMethod(String value) {
      System.out.println("Nested with method: " + value);
    }

    private static final String str = "!\"#$%&";

    @Parameterized.Parameters(name = "{0}")  // <-- от него ни холодно, ни жарко
    Iterable<Character> Symbols() {
      ArrayList<Character> data = new ArrayList<>();
      for (char c : str.toCharArray()) data.add(c);
      return data;
    }

    @ParameterizedTest
    @MethodSource("Symbols")
    void testNesteParamsWithMethod2(Character value) {
      System.out.println("Nested with method: " + value);
    }
  }
}

(Pavel) #4

Уже разобрался, спасибо) А без аннотации @TestInstance(TestInstance.Lifecycle.PER_CLASS) правильно вызывать параметрические тесты?