Параллельное тестирование с JUnit 5 и Selenium [Учебное пособие]

от автора

Параллельное выполнение тестов с Selenium является одним из основных факторов, способных повлиять на скорость их выполнения. Последовательное выполнение в автоматизированном тестировании Selenium будет эффективным только тогда, когда тесты будут выполняться для небольшого числа комбинаций браузеров и ОС. Следовательно, параллельное выполнение следует использовать на ранних стадиях QA-тестирования, чтобы быстро ускорить проведение тестов.

Хотя вы можете воспользоваться преимуществами параллельного тестирования в Selenium, используя локальную Selenium Grid, это может оказаться нецелесообразным, если вы хотите проводить тестирование на множестве браузеров, операционных систем и устройств. В этом случае тестирование на облачной Selenium Grid, такой как LamdaTest, будет наиболее выгодным. Она поможет ускорить параллельное выполнение тестов, используя преимущества, которые предлагает Selenium Grid.

Будучи Java-разработчиком, я активно использую возможности фреймворка JUnit 5 для различных сценариев тестирования, включая параллельное тестирование с Selenium. JUnit 5 значительно отличается от своего предшественника (т.е. JUnit 4), причем различия начинаются с архитектуры ядра. Если вы только начинаете работать с JUnit 5, советую внимательно изучить архитектуру JUnit 5, чтобы понять, как запускать тесты с помощью этого фреймворка.

В этом учебном пособии будет подробно рассказано о том, как проводить параллельное выполнение тестов с помощью фреймворка JUnit 5. Некоторые функции  JUnit 5 все еще находятся в экспериментальной фазе, включая параллельное выполнение тестов. Но, вы можете поделиться своими ценными отзывами с командой JUnit, что поможет в продвижении этой функции для выведения ее из экспериментальной фазы.

Введение во фреймворк JUnit 5

Прежде чем погрузиться в самую суть параллельного выполнения тестов JUnit 5, разрешите кратко описать основные характеристики фреймворка JUnit 5. В JUnit 4 все функциональные возможности упакованы в один пакет. В свою очередь, JUnit 5 состоит из трех отдельных подкомпонентов — JUnit Platform, JUnit Jupiter и JUnit Vintage.

Существует значительная разница в аннотациях JUnit 5 и JUnit 4. Хотя некоторые аннотации в JUnit 5 изменились с точки зрения именования, такие как @Rule и @ClassRule были удалены, а новые, @ExtendWith и @RegisterExtension, добавились в JUnit 5.

Для тех, кто использует JUnit 4, рекомендуем сравнить JUnit 4 с JUnit 5, чтобы понять различия между двумя версиями этих фреймворков. Существует множество причин, по которым JUnit 5 имеет огромное превосходство перед JUnit 4; однако, чтобы понять основные преимущества, проверьте, почему следует использовать JUnit 5.

Ниже показано архитектурное представление фреймворка JUnit 5:

Архитектура JUnit 5
Архитектура JUnit 5

В целом, JUnit 5 гораздо более расширяем благодаря своей уникальной архитектуре, обеспечивает гибкость при использовании нескольких раннеров и предоставляет набор полезных аннотаций, которые улучшают тесты.

Параллельное выполнение тестов в JUnit 5

Теперь, когда мы разобрали основные аспекты свойств фреймворка JUnit 5, рассмотрим, как осуществить параллельное выполнение тестов в JUnit 5 с точки зрения автоматизации тестирования Selenium. Для выполнения тестов потребуется рабочая настройка JUnit на вашей машине. Обязательно ознакомьтесь с нашим блогом о том, как настроить среду JUnit, в котором описанные шаги остаются неизменными и для JUnit 5.

Давайте перейдем к вопросу «Как запускать тесты JUnit 5 параллельно»? Во-первых, параллельное выполнение тестов JUnit 5 все еще находится в экспериментальной стадии, и, как ожидается, станет основной функцией в предстоящем релизе JUnit 5. Итак, чтобы включить параллельное выполнение тестов в JUnit 5, установите junit.jupiter.execution.parallel.enabled в true в файле junit-platform.properties.

Читайте — Как выполнять тесты JUnit 4 с помощью JUnit 5

Даже после установки вышеуказанного свойства в true тестовые классы и тестовые методы все равно будут выполняться последовательно. SAME_THREAD и CONCURRENT — это два режима, позволяющие контролировать последовательность выполнения тестов. Как указано в официальной документации пользователя JUnit 5, SAME_THREAD (режим выполнения по умолчанию) заставляет тест выполняться в том же потоке, который использует его родитель. С другой стороны, CONCURRENT позволяет выполнять тесты одновременно в разных, если блокировка ресурсов не заставляет выполнять их в одном потоке.

Вот параметры конфигурации для параллельного выполнения всех тестов JUnit 5:

junit.jupiter.execution.parallel.enabled = true junit.jupiter.execution.parallel.mode.default = concurrent

Как только свойство параллельного выполнения установлено (или включено), движок JUnit Jupiter будет выполнять тесты параллельно в соответствии с конфигурациями, предоставляемыми механизмами синхронизации. В следующем разделе руководства по JUnit 5 мы подробно рассмотрим практическую реализацию параллельного выполнения тестов JUnit 5 для автоматизированного тестирования Selenium.

Если вы являетесь экспертом по Java, с помощью бесплатной сертификации JUnit вы можете получить признание своих знаний и продвинуться по карьерной лестнице.

Эта сертификация JUnit устанавливает стандарты тестирования для тех, кто хочет развивать свою карьеру в области автоматизированного тестирования Selenium с JUnit.

Вот краткий обзор сертификации JUnit от LambdaTest:

Демонстрация: Параллельное выполнение тестов JUnit 5 для автоматизированного тестирования Selenium

Давайте приступим к демонстрации параллельного выполнения тестов с помощью JUnit 5. Сначала рассмотрим простой пример на Java, состоящий из двух классов, выполняемых параллельно с использованием фреймворка JUnit 5.

Давайте рассмотрим простой пример параллельного выполнения тестов JUnit 5.

FileName – Test1.java

package SimpleTest;   import org.junit.jupiter.api.*;   public class Test1 {      @BeforeAll    public static void start() {        System.out.println("=======Starting junit 5 tests========");    }      @BeforeEach    public void setup() {        System.out.println("=======Setting up the prerequisites========");      }    @Test    void test1_FirstTest() {        System.out.println(Thread.currentThread().getStackTrace()[1]                .getMethodName()+" => executed successfully");    }      @Test    void test1_SecondTest() {        System.out.println(Thread.currentThread().getStackTrace()[1]                .getMethodName()+" => executed successfully");    }      @Test    void test1_ThirdTest() {        System.out.println(Thread.currentThread().getStackTrace()[1]                .getMethodName()+" => executed successfully");    }    @Test    void test1_FourthTest() {        System.out.println(Thread.currentThread().getStackTrace()[1]                .getMethodName()+" => executed successfully");    }        @AfterEach    public void tearDown() {        System.out.println("Tests ended");    }      @AfterAll    public static void end() {        System.out.println("All the tests are executed");      } }

FileName – Test2.java

package SimpleTest; import org.junit.jupiter.api.*;   public class Test2 {    @BeforeAll    public static void start() {        System.out.println("=======Starting junit 5 tests========");    }    @BeforeEach    public void setup() {        System.out.println("=======Setting up the prerequisites========");    }      @Test    void test2_FirstTest() {        System.out.println(Thread.currentThread().getStackTrace()[1]                .getMethodName()+" => executed successfully");    }    @Test    void test2_SecondTest() {        System.out.println(Thread.currentThread().getStackTrace()[1]                .getMethodName()+" => executed successfully");    }      @Test    void test2_ThirdTest() {        System.out.println(Thread.currentThread().getStackTrace()[1]                .getMethodName()+" => executed successfully");    }    @Test    void test2_FourthTest() {        System.out.println(Thread.currentThread().getStackTrace()[1]                .getMethodName()+" => executed successfully");    }    @AfterEach    public void tearDown() {        System.out.println("Tests ended");    }    @AfterAll    public static void end() {        System.out.println("All the tests are executed");    } }

FileName – pom.xml

<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0"         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">    <modelVersion>4.0.0</modelVersion>      <groupId>org.example</groupId>    <artifactId>ParallelTest</artifactId>    <version>1.0-SNAPSHOT</version>      <properties>        <maven.compiler.source>1.8</maven.compiler.source>        <maven.compiler.target>${maven.compiler.source}</maven.compiler.target>        <junit.jupiter.version>5.7.1</junit.jupiter.version>    </properties>      <dependencies>        <dependency>            <groupId>org.junit.jupiter</groupId>            <artifactId>junit-jupiter-engine</artifactId>            <version>${junit.jupiter.version}</version>            <scope>test</scope>        </dependency>        <dependency>            <groupId>org.junit.jupiter</groupId>            <artifactId>junit-jupiter-api</artifactId>            <version>${junit.jupiter.version}</version>            <scope>test</scope>        </dependency>        <dependency>            <groupId>org.seleniumhq.selenium</groupId>            <artifactId>selenium-java</artifactId>            <version>3.141.59</version>        </dependency>        <dependency>            <groupId>org.junit.jupiter</groupId>            <artifactId>junit-jupiter-params</artifactId>            <version>5.7.1</version>            <scope>test</scope>        </dependency>    </dependencies> </project>

Итак, как мы можем запускать тестовые сценарии JUnit 5 параллельно? Фреймворк JUnit 5 предоставляет для этого два различных механизма:

Способ 1: Добавить аргументы VM в конфигурацию Run

Шаг 1: Кликните правой кнопкой мыши по папке, содержащей тесты, которые вы собираетесь запускать параллельно. Кликните Create Tests (Создать тесты).

Шаг 2: В конфигурации Create Run добавьте следующие аргументы в опциях VM:

-Djunit.jupiter.execution.parallel.enabled=true -Djunit.jupiter.execution.parallel.mode.default=concurrent

Шаг 3: Нажмите OK и запустите тесты.

Из результатов видно, что тесты JUnit 5 выполняются параллельно.

Результат выполнения

Метод 2: Параллельное выполнение тестов JUnit 5 с помощью Maven

В этом специфическом методе опции параллельного выполнения добавляются в файл pom.xml. Если вы новичок в Maven, то можете быстро просмотреть учебник Maven для Selenium, который поможет начать работу с Maven для Eclipse IDE.

Для демонстрации мы использовали предыдущий пример, в котором два теста в разных Java-файлах выполнялись параллельно. Выполните следующие шаги, чтобы реализовать параллельное выполнение в JUnit 5 с помощью указанного подхода:

Шаг 1: Установите junit.jupiter.execution.parallel.enabled в true и junit.jupiter.execution.parallel.mode.default в concurrent в pom.xml.

<build>    <plugins>        <plugin>            <artifactId>maven-surefire-plugin</artifactId>            <version>2.22.1</version>            <configuration>                <properties>                    <configurationParameters>                        junit.jupiter.execution.parallel.enabled=true                        junit.jupiter.execution.parallel.mode.default=concurrent                    </configurationParameters>                </properties>            </configuration>        </plugin>    </plugins> </build>

Шаг 2: Выполните команду Maven mvn clean test, чтобы запустить тесты из командной строки. Если вас заинтересовала информация о выполнении командной строки с Maven для JUnit, обязательно ознакомьтесь с нашим подробным блогом, демонстрирующим выполнение тестов JUnit из командной строки.

Ниже показан снапшот выполнения, который свидетельствует об успешном завершении теста:

Если вам интересно узнать больше о других основных возможностях фреймворка JUnit, перейдите к подробному руководству по JUnit на учебном хабе LambdaTest.

Как осуществить параллельное выполнение тестов JUnit 5 с помощью Selenium

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

LambdaTest предоставляет отличную платформу для запуска Selenium-тестов на 2000+ браузерах и операционных системах, и все это в облаке! Более того, поскольку изменения кода касаются в основном инфраструктуры, можно легко перенести существующую реализацию с локальной Selenium Grid на облачную.

После создания учетной записи на LambdaTest обязательно запишите имя пользователя и ключ доступа, которые доступны на странице профиля LambdaTest. Затем вы можете сгенерировать желаемые функции для комбинаций браузера и платформы с помощью генератора возможностей на LambdaTest.

Ниже приведен код для запуска наших тестов Junit 5 на облачной Selenium Grid, типа LambdaTest:

FileName — RunningTestsInParallelInGrid.java

import org.openqa.selenium.By; import org.junit.jupiter.api.*; import org.openqa.selenium.WebElement; import org.openqa.selenium.interactions.Actions; import org.openqa.selenium.remote.DesiredCapabilities; import org.openqa.selenium.remote.RemoteWebDriver; import org.openqa.selenium.support.ui.ExpectedConditions; import org.openqa.selenium.support.ui.WebDriverWait; import java.net.MalformedURLException; import java.net.URL; import java.util.List; import java.util.concurrent.TimeUnit; public class RunningTestsInParallelInGrid {   String username = "YOUR_USERNAME"; //Enter your username   String accesskey = "YOUR_ACCESS_KEY"; //Enter your accesskey   static RemoteWebDriver driver = null;   String gridURL = "@hub.lambdatest.com/wd/hub";   String urlToTest = "https://www.lambdatest.com/";   @BeforeAll   public static void start() {       System.out.println("=======Running junit 5 tests in parallel in LambdaTest Grid has started========");   }   @BeforeEach   public void setup() {       System.out.println("Setting up the drivers and browsers");       DesiredCapabilities capabilities = new DesiredCapabilities();       capabilities.setCapability("browserName", "chrome");   //To specify the browser       capabilities.setCapability("version", "70.0");    //To specify the browser version       capabilities.setCapability("platform", "win10");      // To specify the OS       capabilities.setCapability("build", "Running_ParallelJunit5Tests_In_Grid");               //To identify the test       capabilities.setCapability("name", "Parallel_JUnit5Tests");       capabilities.setCapability("network", true);      // To enable network logs       capabilities.setCapability("visual", true);          // To enable step by step screenshot       capabilities.setCapability("video", true);       // To enable video recording       capabilities.setCapability("console", true);         // To capture console logs       try {           driver = new RemoteWebDriver(new URL("https://" + username + ":" + accesskey + gridURL), capabilities);       } catch (MalformedURLException e) {           System.out.println("Invalid grid URL");       } catch (Exception e) {           System.out.println(e.getMessage());       }   }   @Test   @DisplayName("Title_Test")   @Tag("Sanity")   public void launchAndVerifyTitle_Test() {       String methodName = Thread.currentThread()               .getStackTrace()[1]               .getMethodName();       System.out.println("********Execution of "+methodName+" has been started********");       System.out.println("Launching LambdaTest website started..");       driver.get(urlToTest);       driver.manage().window().maximize();       driver.manage().timeouts().pageLoadTimeout(10, TimeUnit.SECONDS);       String actualTitle = driver.getTitle();       System.out.println("The page title is "+actualTitle);       String expectedTitle ="Most Powerful Cross Browser Testing Tool Online | LambdaTest";       System.out.println("Verifying the title of the webpage started");       Assertions.assertEquals(expectedTitle, actualTitle);       System.out.println("The webpage has been launched and the title of the webpage has been veriified successfully");       System.out.println("********Execution of "+methodName+" has ended********");   }   @Test   @DisplayName("Login_Test")   @Tag("Sanity")   public void login_Test() {       String methodName = Thread.currentThread()               .getStackTrace()[1]               .getMethodName();       System.out.println("********Execution of "+methodName+" has been started********");       System.out.println("Launching LambdaTest website started..");       driver.get(urlToTest);       driver.manage().window().maximize();       driver.manage().timeouts().pageLoadTimeout(10, TimeUnit.SECONDS);       WebElement login = driver.findElement(By.xpath("//a[text()='Login']"));       login.click();       WebElement username = driver.findElement(By.xpath("//input[@name=\"email\"]"));       WebElement password = driver.findElement(By.xpath("//input[@name=\"password\"]"));       WebDriverWait wait = new WebDriverWait(driver,20);       wait.until(ExpectedConditions.visibilityOf(username));       username.clear();       username.sendKeys("acvdd@gmail.com");       password.clear();       password.sendKeys("abc@123");       WebElement loginButton = driver.findElement(By.xpath("//button[text()='Login']"));       loginButton.click();       driver.manage().timeouts().pageLoadTimeout(10, TimeUnit.SECONDS);       String actual = driver.getTitle();       String expected = "Welcome - LambdaTest";       Assertions.assertEquals(expected, actual);       System.out.println("The user has been successfully logged in");       System.out.println("********Execution of "+methodName+" has ended********");   }   @Test   @DisplayName("Logo_Test")   public void logo_Test() {       String methodName = Thread.currentThread()               .getStackTrace()[1]               .getMethodName();       System.out.println("********Execution of "+methodName+" has been started********");       System.out.println("Launching LambdaTest website started..");       driver.get(urlToTest);       driver.manage().window().maximize();       driver.manage().timeouts().pageLoadTimeout(10, TimeUnit.SECONDS);       System.out.println("Verifying of webpage logo started..");       WebElement logo = driver.findElement(By.xpath("//*[@id=\"header\"]/nav/div/div/div[1]/div/a/img"));       boolean is_logo_present = logo.isDisplayed();       if(is_logo_present) {           System.out.println("The logo of LambdaTest is displayed");       }       else {           Assertions.assertFalse(is_logo_present,"Logo is not present");       }       System.out.println("********Execution of "+methodName+" has ended********");   }   @Test   @DisplayName("Blog_Test")   public void blogPage_Test() {       String methodName = Thread.currentThread()               .getStackTrace()[1]               .getMethodName();       System.out.println("********Execution of "+methodName+" has been started********");       System.out.println("Launching LambdaTest website started..");       driver.get(urlToTest);       driver.manage().window().maximize();       driver.manage().timeouts().pageLoadTimeout(10, TimeUnit.SECONDS);       WebElement resources = driver.findElement(By.xpath("//*[text()='Resources ']"));       List<WebElement> options_under_resources = driver.findElements(By.xpath("//*[text()='Resources ']/../ul/a"));       boolean flag = resources.isDisplayed();       if(flag) {           System.out.println("Resources header is visible in the webpage");           Actions action = new Actions(driver);           action.moveToElement(resources).build().perform();           WebDriverWait wait=new WebDriverWait(driver, 20);           wait.until(ExpectedConditions.visibilityOfAllElements(options_under_resources));           for(WebElement element : options_under_resources) {               if(element.getText().equals("Blog")){                   System.out.println("Clicking Blog option has started");                   element.click();                   System.out.println("Clicking Blog option has ended");                   driver.manage().timeouts().pageLoadTimeout(20,TimeUnit.SECONDS);                   Assertions.assertEquals("LambdaTest Blogs", driver.getTitle());                   break;               }               else                   Assertions.fail("Blogs option is not available");           }       }       else {           Assertions.fail("Resources header is not visible");       }       System.out.println("********Execution of "+methodName+" has ended********");   }   @Test   @DisplayName("Cerification_Test")   public void certificationPage_Test() {       String methodName = Thread.currentThread()               .getStackTrace()[1]               .getMethodName();       System.out.println("********Execution of "+methodName+" has been started********");       System.out.println("Launching LambdaTest website started..");       driver.get(urlToTest);       driver.manage().window().maximize();       driver.manage().timeouts().pageLoadTimeout(10, TimeUnit.SECONDS);       WebElement resources = driver.findElement(By.xpath("//*[text()='Resources ']"));       List<WebElement> options_under_resources = driver.findElements(By.xpath("//*[text()='Resources ']/../ul/a"));       boolean flag = resources.isDisplayed();       if(flag) {           System.out.println("Resources header is visible in the webpage");           Actions action = new Actions(driver);           action.moveToElement(resources).build().perform();           WebDriverWait wait = new WebDriverWait(driver, 20);           wait.until(ExpectedConditions.visibilityOfAllElements(options_under_resources));           for (int i = 0; i < options_under_resources.size(); i++) {               String value = options_under_resources.get(i).getText();               if (value.equals("Certifications")) {                   System.out.println("Clicking Certifications option has started");                   action.moveToElement(options_under_resources.get(i)).build().perform();                   options_under_resources.get(i).click();                   System.out.println("Clicking Certifications option has ended");                   driver.manage().timeouts().pageLoadTimeout(20, TimeUnit.SECONDS);                   String expectedCertificationPageTitle = "LambdaTest Selenium Certifications - Best Certifications For Automation Testing Professionals";                   String actualCertificationPageTitle = driver.getTitle();                   Assertions.assertEquals(expectedCertificationPageTitle, actualCertificationPageTitle);                   break;               }           }       }       System.out.println("********Execution of "+methodName+" has ended********");   }   @Test   @DisplayName("Support_Test")   public void supportPage_Test() {       String methodName = Thread.currentThread()               .getStackTrace()[1]               .getMethodName();       System.out.println("********Execution of "+methodName+" has been started********");       System.out.println("Launching LambdaTest website started..");       driver.get(urlToTest);       driver.manage().window().maximize();       driver.manage().timeouts().pageLoadTimeout(10, TimeUnit.SECONDS);       WebElement supportHeader = driver.findElement(By.xpath("(//div//*[text()='Support'])[1]"));       boolean flag = supportHeader.isDisplayed();       if(flag) {           System.out.println("support header is visible in the webpage");           supportHeader.click();       }       else {           Assertions.fail("support header is not visible");       }       System.out.println("********Execution of "+methodName+" has ended********");   }   @AfterEach   public void tearDown() {       System.out.println("Quitting the browsers has started");       driver.quit();       System.out.println("Quitting the browsers has ended");   }   @AfterAll   public static void end() {       System.out.println("Tests ended");   } }

Как упоминалось ранее, параллельное выполнение тестов JUnit 5 может быть достигнуто путем добавления аргументов в опциях VM в конфигурации Run или запуском через Maven путем добавления плагина в файл pom.xml.

Обзор кода

Вместо того чтобы подробно разбирать код, остановимся на наиболее важных аспектах.

Для начала создадим экземпляр Remote WebDriver, используя возможности браузера и платформы, добавленные в методе setup(). Затем, как показано ниже, для доступа к LambdaTest Grid используется пара — имя пользователя/ключ доступа.

driver = new RemoteWebDriver(new URL("https://" + username + ":" + accesskey + gridURL), capabilities);

Класс включает в себя 6 методов тестирования, причем каждый метод применяет соответствующие локаторы Selenium для поиска соответствующих Web-элементов. Например, в тестовом методе login_Test() локатор XPath Selenium используется для поиска элементов email и password на странице. Если вам нужен краткий обзор XPath, обязательно ознакомьтесь с нашим подробным руководством по использованию локаторов XPath в Selenium.

WebElement username = driver.findElement(By.xpath("//input[@name=\"email\"]")); WebElement password = driver.findElement(By.xpath("//input[@name=\"password\"]"));

При выполнении теста существует вероятность того, что динамически загруженный контент (или Web-элемент) может отсутствовать на странице. Взаимодействие с элементом, который пока не является частью DOM, может привести к исключениям. Поскольку работа с динамическим содержимым является одной из основных проблем автоматизации Selenium, ее необходимо решать путем добавления подходящей задержки (задержек), чтобы сделать соответствующий WebElement доступным для доступа в DOM.

driver.manage().timeouts().pageLoadTimeout(10, TimeUnit.SECONDS);

Предполагаемые условия в Selenium WebDriver используются в соответствующих местах реализации для обеспечения того, что Web-элементы, с которыми осуществляется взаимодействие, были видимыми, интерактивными и т. д. Например, в тестовом методе blogPage_Test() выполняется ожидание условия visibilityOfAllElements (видимость всех элементов). Затем, если определенные элементы видимы, с ними выполняются надлежащие действия.

wait.until(ExpectedConditions.visibilityOfAllElements(options_under_resources));

Утверждения (asserts) JUnit с Selenium используются во всех методах тестирования для подтверждения сбоев, возникающих в процессе автоматизированного тестирования Selenium. Ниже приведены некоторые ассерты из нескольких методов тестирования:

Assertions.assertEquals(expectedCertificationPageTitle, actualCertificationPageTitle); Assertions.assertFalse(is_logo_present,"Logo is not present");

Выполнение

Ниже показан снапшот выполнения, свидетельствующий о параллельном исполнении тестов:

Как показано ниже, мы видим, что выполнение теста завершилось успешно.

Параллельное тестирование с junit 5
Параллельное тестирование с junit 5

Чтобы проверить статус выполнения теста, перейдите на дашборд автоматизации LambdaTest, где можно даже посмотреть видео.

Дашборд автоматизации LambdaTest
Дашборд автоматизации LambdaTest

Как осуществить параллельное выполнение тестов JUnit 5 с помощью параметризации в Selenium

В предыдущем разделе мы выполнили шесть различных тестов на одной комбинации браузера и платформы. Однако такой подход может дать сбой, если тесты необходимо выполнить сочетаниями по «N» различных комбинаций.

Именно здесь параметризованное тестирование с помощью JUnit в Selenium будет очень эффективным, поскольку соответствующие комбинации тестов могут быть переданы в качестве параметров параметризованным методам тестирования. Как и его предшественник, JUnit 5 также обладает гибкостью, позволяющей использовать параметризацию в Selenium для сокращения LOC (Lines of Code) и достижения лучшего покрытия тестов меньшим количеством кода.

Добавьте следующую зависимость в pom.xml, чтобы вы могли параметризовать тесты с помощью фреймворка JUnit 5:

<dependency>    <groupId>org.junit.jupiter</groupId>    <artifactId>junit-jupiter-params</artifactId>    <version>5.7.1</version>    <scope>test</scope> </dependency>

Для демонстрации мы будем проводить тесты на браузерах Chrome и Firefox на LambdaTest Selenium Grid. Комбинации браузеров и платформ создаются с помощью генератора возможностей LambdaTest.

FileName — crossBrowserTests.java

package crossBrowserTests;   import org.junit.jupiter.api.*; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource;   import org.openqa.selenium.By; import org.openqa.selenium.WebElement; import org.openqa.selenium.remote.DesiredCapabilities; import org.openqa.selenium.remote.RemoteWebDriver; import org.openqa.selenium.support.ui.ExpectedConditions; import org.openqa.selenium.support.ui.WebDriverWait;   import java.net.MalformedURLException; import java.net.URL; import java.util.concurrent.TimeUnit; import java.util.stream.Stream;   import static org.junit.jupiter.params.provider.Arguments.arguments;   public class crossBrowserTest {      String username = "user_name"; //Enter your username    String accesskey = "access_key"; //Enter your accesskey      static RemoteWebDriver driver = null;    String gridURL = "@hub.lambdatest.com/wd/hub";    String urlToTest = "https://www.lambdatest.com/";      @BeforeAll    public static void start() {        System.out.println("=======Starting junit 5 tests in LambdaTest Grid========");    }      @BeforeEach    public void setup(){        System.out.println("=======Setting up drivers and browser========");    }      public void browser_setup(String browser) {        System.out.println("Setting up the drivers and browsers");        DesiredCapabilities capabilities = new DesiredCapabilities();          if(browser.equalsIgnoreCase("Chrome")) {            capabilities.setCapability("browserName", "chrome");    //To specify the browser            capabilities.setCapability("version", "70.0");        //To specify the browser version            capabilities.setCapability("platform", "win10");        // To specify the OS            capabilities.setCapability("build", "Running_Junit5Tests_In_Grid_Chrome");               //To identify the test            capabilities.setCapability("name", "JUnit5Tests_Chrome");            capabilities.setCapability("network", true);        // To enable network logs            capabilities.setCapability("visual", true);            // To enable step by step screenshot            capabilities.setCapability("video", true);            // To enable video recording            capabilities.setCapability("console", true);            // To capture console logs        }        if(browser.equalsIgnoreCase("Firefox")) {            capabilities.setCapability("browserName", "Firefox");  //To specify the browser            capabilities.setCapability("version", "76.0");    //To specify the browser version            capabilities.setCapability("platform", "win10");   // To specify the OS            capabilities.setCapability("build", "Running_Junit5Tests_In_Grid_Firefox");    //To identify the test            capabilities.setCapability("name", "JUnit5Tests_Firefox");            capabilities.setCapability("network", true);      // To enable network logs            capabilities.setCapability("visual", true);       // To enable step by step screenshot            capabilities.setCapability("video", true);        // To enable video recording            capabilities.setCapability("console", true);      // To capture console logs          }        try {            driver = new RemoteWebDriver(new URL("https://" + username + ":" + accesskey + gridURL), capabilities);        } catch (MalformedURLException e) {            System.out.println("Invalid grid URL");        } catch (Exception e) {            System.out.println(e.getMessage());        }      }      @ParameterizedTest    @MethodSource("browser")    public void launchAndVerifyTitle_Test(String browser) {        browser_setup(browser);        String methodName = Thread.currentThread()                .getStackTrace()[1]                .getMethodName();        System.out.println("********Execution of "+methodName+" has been started********");        System.out.println("Launching LambdaTest website started..");        driver.get(urlToTest);        driver.manage().window().maximize();        driver.manage().timeouts().pageLoadTimeout(10, TimeUnit.SECONDS);        String actualTitle = driver.getTitle();        System.out.println("The page title is "+actualTitle);        String expectedTitle ="Most Powerful Cross Browser Testing Tool Online | LambdaTest";        System.out.println("Verifying the title of the webpage started");        Assertions.assertEquals(expectedTitle, actualTitle);        System.out.println("The webpage has been launched and the title of the webpage has been veriified successfully");        System.out.println("********Execution of "+methodName+" has ended********");    }      @ParameterizedTest    @MethodSource("browser")    public void login_Test(String browser) {        browser_setup(browser);          String methodName = Thread.currentThread()                .getStackTrace()[1]                .getMethodName();        System.out.println("********Execution of "+methodName+" has been started********");        System.out.println("Launching LambdaTest website started..");        driver.get(urlToTest);        driver.manage().window().maximize();        driver.manage().timeouts().pageLoadTimeout(10, TimeUnit.SECONDS);        WebElement login = driver.findElement(By.xpath("//a[text()='Login']"));        login.click();        WebElement username = driver.findElement(By.xpath("//input[@name='email']"));        WebElement password = driver.findElement(By.xpath("//input[@name='password']"));        WebDriverWait wait = new WebDriverWait(driver,20);        wait.until(ExpectedConditions.visibilityOf(username));        username.clear();        username.sendKeys("abcwdwd@gmail.com");        password.clear();        password.sendKeys("abc@123");        WebElement loginButton = driver.findElement(By.xpath("//button[text()='Login']"));        loginButton.click();        driver.manage().timeouts().pageLoadTimeout(10, TimeUnit.SECONDS);        String actual = driver.getTitle();        String expected = "Welcome - LambdaTest";        Assertions.assertEquals(expected, actual);        System.out.println("The user has been successfully logged in");        System.out.println("********Execution of "+methodName+" has ended********");    }      @ParameterizedTest    @MethodSource("browser")    public void logo_Test(String browser) {        browser_setup(browser);        String methodName = Thread.currentThread()                .getStackTrace()[1]                .getMethodName();        System.out.println("********Execution of "+methodName+" has been started********");        System.out.println("Launching LambdaTest website started..");        driver.get(urlToTest);        driver.manage().window().maximize();        driver.manage().timeouts().pageLoadTimeout(10, TimeUnit.SECONDS);        System.out.println("Verifying of webpage logo started..");          WebElement logo = driver.findElement(By.xpath("//*[@id=\"header\"]/nav/div/div/div[1]/div/a/img"));        boolean is_logo_present = logo.isDisplayed();        if(is_logo_present) {            System.out.println("The logo of LambdaTest is displayed");        }        else {            Assertions.assertFalse(is_logo_present,"Logo is not present");        }        System.out.println("********Execution of "+methodName+" has ended********");    }      @AfterEach    public void tearDown() {        System.out.println("Quitting the browsers has started");        driver.quit();        System.out.println("Quitting the browsers has ended");    }      @AfterAll    public static void end() {        System.out.println("Tests ended");    }      static Stream<Arguments> browser() {        return Stream.of(                arguments("Chrome"),                arguments("Firefox")        );    } }

Краткое описание кода

Поскольку мы используем параметризацию в JUnit 5, необходимый пакет импортируется в начале процесса имплементации.

import org.junit.jupiter.params.ParameterizedTest;

Также импортируется пакет org.junit.jupiter.params.provider, поскольку поток физических аргументов будет использоваться в качестве входных данных для аннотированного метода @ParameterizedTest.

import static org.junit.jupiter.params.provider.Arguments.arguments;

Поток аргументов Browser определяется так, как показано ниже. Каждый метод тестирования использует ‘browser’ в качестве входного аргумента, по которому выполняются методы тестирования.

static Stream<Arguments> browser() {        return Stream.of(                arguments("Chrome"),                arguments("Firefox")        );    }

Каждый метод тестирования вызывает метод browser_setup(), в котором устанавливаются соответствующие возможности браузера и платформы в зависимости от определенной комбинации тестов. Например, удаленный драйвер Chrome инстанцируется, если параметр (т.е. браузер) установлен на Chrome. Тот же принцип применим и к браузеру Firefox.

public void browser_setup(String browser) {        System.out.println("Setting up the drivers and browsers");        DesiredCapabilities capabilities = new DesiredCapabilities();          if(browser.equalsIgnoreCase("Chrome")) {      .............................................            .............................................            .............................................

Поскольку каждый метод теста является параметризованным, он определяется под аннотацией @ParameterizedTest. Аналогично, аннотация @MethodSource используется для доступа к значениям, возвращаемым из фабричных методов класса, под которым объявлена аннотация.

Как видно ниже, @MethodSource предоставляет доступ к значению «browser», которое представляет собой поток аргументов (т.е. Stream< Arguments >). Следовательно, три метода тестирования [т.е. launchAndVerifyTitle_Test(), login_Test() и logo_Test()] будут запущены в двух комбинациях браузеров (т.е. Chrome и Firefox).

@ParameterizedTest    @MethodSource("browser")    public void launchAndVerifyTitle_Test(String browser) {        browser_setup(browser);        String methodName = Thread.currentThread()                .getStackTrace()[1]                .getMethodName();        ...................................        ...................................        ...................................

Таким образом, вы должны увидеть шесть тестовых сценариев, выполняющихся параллельно на Selenium Grid LambdaTest. Помимо этих изменений, остальная логика имплементации остается прежней, как упоминалось ранее.

Метод tearDown(), определенный в аннотации @AfterEach, выполняется после каждого запуска теста, чтобы последующие тесты выполнялись на новой комбинации браузера и ОС.

@AfterEach public void tearDown() {        System.out.println("Quitting the browsers has started");        driver.quit();        System.out.println("Quitting the browsers has ended"); }

Метод, определенный в аннотации @AfterAll, выполняется только после завершения выполнения всех тестов.

@AfterAll public static void end() {    System.out.println("Tests ended"); }

Выполнение

Ниже показан снапшот процесса, который показывает, что параллельное выполнение тестов с использованием JUnit 5 было выполнено на браузерах Chrome и Firefox.

Ниже показан снапшот дашборда автоматизации LambdaTest, который показывает, что три метода тестирования были запущены на двух различных комбинациях браузеров (т.е. Chrome и Firefox). Название сборки, отображаемое на дашборде, было установлено при настройке желаемых возможностей браузера.

apabilities.setCapability("build", "Running_Junit5Tests_In_Grid_Chrome");                //To identify the test capabilities.setCapability("name", "JUnit5Tests_Chrome");   ............................................. ............................................. ............................................. capabilities.setCapability("build", "Running_Junit5Tests_In_Grid_Firefox");     //To identify the test capabilities.setCapability("name", "JUnit5Tests_Firefox");

Консоль выполнения IntelliJ показывает, что три теста были успешно выполнены для двух различных комбинаций браузеров.

Заключение

В этом руководстве было рассмотрено, как осуществлять параллельное выполнение тестов с помощью фреймворка JUnit 5 различными способами. Для тестов мы также использовали облачную грид-систему LambdaTest, которая поддерживает 2000+ браузеров и различные платформы. Надеюсь, что эта статья помогла вам разобраться в параллельном выполнении тестов с помощью JUnit 5. 

Продолжайте исследовать!


Материал подготовлен в рамках курса «Java QA Engineer. Professional». Если вам интересно узнать подробнее о формате обучения и программе, познакомиться с преподавателем курса — приглашаем на день открытых дверей онлайн. Регистрация здесь.


ссылка на оригинал статьи https://habr.com/ru/articles/587898/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *