Есть отличная удаленная работа для php+codeception+jenkins+allure+docker спецов. 100% remote! Присоединиться к проекту

Помогите с концепцией DDT JUnit в Thucydides. Как правильно написать тест сценарий?


(heartwilltell) #1

Не совсем понимаю как правильно писать DDT тесты на JUnit

Сам тест мне нужно организовать таким образом :
Открываем страницу
Делаем проверку

Проверка одна, страниц очень много - как сделать так что бы открывало каждую страницу и делало проверку.


(Mykhailo Poliarush) #2

Надо использовать @Parameterized аннотацию. Пример можно посмотреть тут http://www.tutorialspoint.com/junit/junit_parameterized_test.htm

import java.util.Arrays;
import java.util.Collection;
 
import org.junit.Test;
import org.junit.Before;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
import org.junit.runner.RunWith;
import static org.junit.Assert.assertEquals;

@RunWith(Parameterized.class)
public class PrimeNumberCheckerTest {
   private Integer inputNumber;
   private Boolean expectedResult;
   private PrimeNumberChecker primeNumberChecker;

   @Before
   public void initialize() {
      primeNumberChecker = new PrimeNumberChecker();
   }

   // Each parameter should be placed as an argument here
   // Every time runner triggers, it will pass the arguments
   // from parameters we defined in primeNumbers() method
   public PrimeNumberCheckerTest(Integer inputNumber, 
      Boolean expectedResult) {
      this.inputNumber = inputNumber;
      this.expectedResult = expectedResult;
   }

   @Parameterized.Parameters
   public static Collection primeNumbers() {
      return Arrays.asList(new Object[][] {
         { 2, true },
         { 6, false },
         { 19, true },
         { 22, false },
         { 23, true }
      });
   }

   // This test will run 4 times since we have 5 parameters defined
   @Test
   public void testPrimeNumberChecker() {
      System.out.println("Parameterized Number is : " + inputNumber);
      assertEquals(expectedResult, 
      primeNumberChecker.validate(inputNumber));
   }
}

Или у вас более конкретные вопросы? Тогда опишите их подробней, пожалуйста.


(heartwilltell) #3

А какую роль в этом играет PrimeNumberChecker

У меня совсем плохо с оопю Я просто не могу понять как мне передавать драйверу новый юрл.


(Mykhailo Poliarush) #4

Ну это просто пример такой, где PrimeNumberChecker - это класс, который тестируется.

public class PrimeNumberChecker {
   public Boolean validate(final Integer primeNumber) {
      for (int i = 2; i < (primeNumber / 2); i++) {
         if (primeNumber % i == 0) {
            return false;
         }
      }
      return true;
   }
}

Вот можно посмотреть пример по проще http://www.mkyong.com/unittest/junit-4-tutorial-6-parameterized-test/

import java.util.Arrays;
import java.util.Collection;
 
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
 
/**
 * JUnit Parameterized Test
 * @author mkyong
 *
 */
@RunWith(value = Parameterized.class)
public class JunitTest6 {
 
	 private int number;
 
	 public JunitTest6(int number) {
	    this.number = number;
	 }
 
	 @Parameters
	 public static Collection<Object[]> data() {
	   Object[][] data = new Object[][] { { 1 }, { 2 }, { 3 }, { 4 } };
	   return Arrays.asList(data);
	 }
 
	 @Test
	 public void pushTest() {
	   System.out.println("Parameterized Number is : " + number);
	 }
}

(heartwilltell) #5
package MPSAutoTests;

import MPSAutoTests.requirements.Application;
import MPSAutoTests.steps.StepsLandingPage;
import net.thucydides.core.annotations.Managed;
import net.thucydides.core.annotations.ManagedPages;
import net.thucydides.core.annotations.Steps;
import net.thucydides.core.annotations.Story;
import net.thucydides.core.pages.Pages;
import net.thucydides.junit.annotations.TestData;
import net.thucydides.junit.runners.ThucydidesParameterizedRunner;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.openqa.selenium.WebDriver;

import java.util.Arrays;
import java.util.Collection;


@Story(Application.CheckLanding.CheckLandingsPages.class)
@RunWith(ThucydidesParameterizedRunner.class)
public class CheckLandingTest {

    @TestData
    public static Collection<Object[]> testData() {
        Object[][] data = new Object[][] {
                {"http://page.com/landings/land1"},
                {"http://page.com/landings/land2"},
                {"http://page.com/landings/land3"},
                {"http://page.com/landings/land4"}
        };
        return Arrays.asList(data);
    }


    @Managed(uniqueSession = true)
    public WebDriver webdriver;

    @ManagedPages(defaultUrl = "http://page.com")
    public Pages pages;

    @Steps
    StepsLandingPage stepsLandingPage;

    private String url;

    public CheckLandingTest(String url) {
        this.url = url;
    }

    @Test
    public void check_landing_page() {
        webdriver.get(url);
    }

Вот как реализовано у меня на Thucydides

Ругается на java.lang.Exception: No tests found matching Method check_landing_page(MPSAutoTests.CheckLandingTest) from org.junit.internal.requests.ClassRequest@ed8adc0


(sidelnikovmike) #6

А в testNg есть dataprovider, с помощью которого можно было бы реализовать то что нужно.


(sidelnikovmike) #7

А, ну parameters в junit то же самое по сути, что и dataprovider))) только почитал, давненько я junit не использовал. Кстати, наткнулся тут на статейку - может интересно будет- http://www.mkyong.com/unittest/junit-4-vs-testng-comparison/
@polusok можно даже куда нибудь ее еще добавить, мне кажется она интересной и полезной.


(Александр Таранков) #8

Разберитесь как в Фукидиде запускать DDT-тесты. Похоже на то, что ThucydidesParameterizedRunner.class не распознает аннотации @Test от JUnit, возможно для него методы должны быть помечены другой аннотацией

P.S. а заодно название метода поправьте: check_landing_page() не соответствует Java code convention. Правильно будет checkLandingPage()


(Mykhailo Poliarush) #9

Так надо было сразу говорить, что вы используете Thucydides, потому как там используется обертка, а не оригинальный класс.

Ну вроде бы все верно написано. Я специально еще посмотрел описание https://github.com/thucydides-webtests/thucydides/wiki/Data-driven-tests-in-Thucydides и официальный пример из коробки (а попробуйте его запустить, он у вас нормально сработает?! )

Если не сработает, значит есть какой-то дефект в Thucydides и надо репортить на них. А еще лучше пойти в код и разобраться как происходит нахождение методов по аннотации @Test

А еще в Thucydides есть DataDrivenAnnotations с помощью, которого можно загружать данные с внешнего источника в виде csv файла.


(Mykhailo Poliarush) #10

TestNG не работает для Thucydides, так как в нем зашито использование JUnit.


(heartwilltell) #11

Тесты запустились и скипнулись (это понятно потому что). То есть по сути все работает.

 public static class UserSteps {
        public void entersRequest(String request) {}
        public void startsSearch() {}
    }
}

Теперь вот даже не знаю где искать проблему.


(Mykhailo Poliarush) #12

А почему они скипнулись?

Ну ок. Если их пример работает, то значит ошибка где-то у тебя в коде, или просто действительно баг какой-то.

Может быть в названии метода проблема. Хотя это глупо, но просто догадка.

В общем, тогда я бы на твоем месте смотрел в исходный код https://github.com/thucydides-webtests/thucydides/blob/master/thucydides-junit/src/main/java/net/thucydides/junit/runners/ThucydidesParameterizedRunner.java и дебажил.


(sidelnikovmike) #13

Не знал. Ниногда не использовал thyckydides, считаю его ненужным)))


(Aleksey) #14

Это потому что вы пытаетесь запустить конкретный тест, запускайте сразу весь тестовый класс - в таком случае все заработает.

Ну, впрочем, у вас все и так получилось - какая проблема у вас осталась? Ваш пример должен нормально работать.

Да, в данном случае название метода не соответствует стандартному код конвешну.
Но… Thucydides рекомендует использовать именование методов с подчеркиваниями для методов, определенных в Step-классах :slight_smile: (насколько я понимаю, это используется потом для текстовых преобразований при формировании отчетов). Для меня это было неожиданностью, так что не удивляйтесь, если встретите такое в будущем.


(heartwilltell) #15

Блин, вот это я даун, я перепробовал наверное все возможные варианты, и почему-то мне и в голову не пришло что это может быть по причине запуска одиночного теста. Я привык запускать их из ide по одиночке когда пишу и проверяю.

Спасибо огромное. Все работает. Юххххххууууууу

Только теперь вопрос - почему каждый тест оно выполняет в новом браузере. Делает тест - закрывает браузер. Начинает новый тест запускает браузер.
Не то что бы это была проблема, но на это тратится намного больше времени.


(Pnevmoslon) #16

За это поведение отвечает параметр uniqueSession. Посмотрите http://thucydides.info/docs/thucydides/_defining_high_level_tests_in_junit.html пункт 5.2.2


(heartwilltell) #17

Дето в том что он у меня есть [quote=“heartwilltell, post:5, topic:3724”]
uniqueSession = true
[/quote]
Но каждый тест все равно стартует в новом браузере, нужно более детально почитать доку в разделе ddt


(Aleksey) #18

Параметр uniqueSession управляет открытие/закрытием браузера при нескольких тестовых методов, размещенных в одном тестовом классе.
У вас же ситуация другая - вы один и тот же тест класс запускаете несколько раз. В этом случае вам не удастся избавиться от такого поведения, но вы можете менеджить веб-драйвер самостоятельно - это сложнее и не думаю, что это уместно в вашем случае.


(heartwilltell) #19

Да, я тоже думаю что это не проблема. Спасибо всем за помощь и подсказки


(Pnevmoslon) #20

Есть ещё глобальное свойство thucydides.use.unique.browser : Set this to run all web tests in a single browser.

Можно попробовать перед тем как рыть глубже :slight_smile: