Статьи

Параметризация в TestNG — DataProvider и TestNG XML (с примерами)

Автоматизация тестирования, или тестирование автоматизации, как его называют в народе, не так проста, как кажется. Все перестановки и комбинации всех возможных взаимодействий с пользователем должны быть рассмотрены и основаны на том, что вам нужно будет создать тестовый сценарий для проверки вашего веб-приложения в многочисленных браузерах + комбинациях ОС. Именно здесь Параметризация играет ключевую роль в автоматизации тестирования Selenium. В этом руководстве по TestNG я покажу вам, как выполнить параметризацию в TestNG для автоматизации тестирования Selenium.

Почему мы параметризуем?

В реальном мире для тестирования веб-интерфейса мы ожидаем, что наш веб-сайт или веб-приложение будут работать корректно с различными входными данными, и практически невозможно проверить наши сценарии только с одним набором данных. Таким образом, мы гарантируем, что наше приложение функционирует должным образом, когда подвергается воздействию различных наборов данных или различных комбинаций для браузеров и ОС. Несколько тестовых комбинаций означают несколько входных значений.

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

Как мы выполняем параметризацию? И зачем использовать TestNG?

Если ваше приложение предполагает ввод различных типов пользовательских взаимодействий, то параметризация — это путь. Мы можем параметризовать наши сценарии автоматизации согласно используемой среде, например, Параметризация в среде TestNG для автоматизации тестирования Selenium. Мы можем рассмотреть возможность использования файлов Excel для извлечения наборов данных и последующего использования их в наших сценариях автоматизации, но по мере того, как мы совершенствуем наш пакет автоматизации, возникает необходимость в использовании более надежных сред автоматизации тестирования, таких как TestNG, для более широкого охвата широкой категории тестов. , В этом посте мы сконцентрируемся в основном на параметризации в TestNG, на каких путях это можно сделать в TestNG и как нам написать эти параметры в наших сценариях тестирования автоматизации Selenium. Давайте сначала начнем с понимания различных типов параметризации в TestNG и того, как мы можем достичь того же.

Типы параметризации в TestNG

Поэтому в первую очередь мы можем добиться параметризации в TestNG двумя способами.

  1. Использование «Аннотации параметров» и XML-файла TestNG.
  2. Использование «аннотации DataProvider».

Параметризация в TestNG с использованием аннотации @Parameters и файла XML

Давайте сначала посмотрим на простой синтаксис написания аннотации параметров в нашем классе:
@Parameter({“parameter name”})

Обратите внимание, что мы также можем использовать более одного параметра в нашей аннотации, которую можно записать так: @Parameters({“param1”,”param2”,”param3”})

На данный момент параметры доступны только для тега Suite или Test в файле testng.xml . Если в Suite и Test передается одно и то же значение параметра, приоритет отдается значению параметра, переданному в теге Test.

Прежде чем мы продолжим с примерами параметризации, мы должны понять, что было бы полезно, если бы использование параметризации в TestNG помогло нашей деятельности по автоматизации тестирования Selenium. Рассмотрим сценарий поиска определенных ключевых слов в поисковой системе, такой как Google. Мы должны были бы написать одинаковые строки кода для каждого ключевого слова, чтобы получить разные результаты, и это неосуществимый подход. Именно здесь в дело вступает параметризация в TestNG или любой другой среде автоматизации тестирования для Selenium. Используя параметризацию в TestNG, вы можете передать эти ключевые слова как различные параметры в testng.xml и добавить аннотацию @parameters в наборе средств автоматизации Selenium. Давайте посмотрим на это на примере.

Сценарий: откройте google.com в своем браузере и выполните поиск по 3 ключевым словам отдельно

Чтобы завершить этот сценарий, вот подробные шаги, которые должен выполнить наш скрипт:

  1. Запустите браузер и откройте www.google.com.
  2. Добавьте первое ключевое слово в качестве ввода в поле поиска и нажмите «Поиск».
  3. Убедитесь, что входное значение в пользовательском интерфейсе совпадает с данными теста.
  4. Повторите два вышеупомянутых шага для двух других ключевых слов.

Ключевое слово для поиска

Селен

QTP

JMeter

Ниже приведен код, показывающий, как мы можем сделать это без параметризации в TestNG.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
package parameterization;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.testng.Assert;
import org.testng.annotations.Test;
public class WithoutParameter {
        WebDriver driver;
        @Test
        public void noParam(){
            //Declaring our first keyword
            String keyWord="Selenium";
            //Initializing Driver
            System.setProperty("webdriver.gecko.driver", "C:\\geckodriver.exe");
            driver = new FirefoxDriver();
            driver.manage().timeouts().pageLoadTimeout(20, TimeUnit.SECONDS);
            //Opening search engine
            driver.get("https://google.com");
            //Finding search text box 
             WebElement searchBox = driver.findElement(By.name("q"));
             //Sending keyword value
             searchBox.sendKeys(keyWord);
             System.out.println("The search keyword entered is : " +keyWord);   
             //Verifying the keyword on UI
             Assert.assertTrue(searchBox.getAttribute("value").equalsIgnoreCase(keyWord));
             driver.quit();
        }
}

Чтобы передать два других ключевых слова, нам нужно будет снова написать тот же фрагмент кода с разными значениями ключевых слов для строки ‘ keyWord ‘, что приведет к длинному и повторяющемуся коду. И в будущем, если вам придется тестировать большее количество ключевых слов, вам придется написать больше тестов.

Давайте теперь упростим нашу задачу, обойдя эти ключевые слова в качестве параметров в нашем testng.xml и добавив аннотацию @parameters в нашем тесте.

Java-код:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
package parameterization;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.testng.Assert;
import org.testng.annotations.Parameters;
import org.testng.annotations.Test;
  
public class ParameterizedClass {
WebDriver driver;  
        @Parameters("keyWord")
        @Test
        public void Parameterpassing(String keyWord){  
            //Initializing Driver
//Mention the path to your local webdriver
            System.setProperty("webdriver.chrome.driver", "D:\\LocalDriver\\chromedriver.exe");
            driver = new ChromeDriver();
            driver.manage().timeouts().pageLoadTimeout(20, TimeUnit.SECONDS);
            //Opening search engine
            driver.get("https://google.com");
            //Finding search text box 
             WebElement searchBox = driver.findElement(By.name("q"));
             //Sending keyword value
             searchBox.sendKeys(keyWord);
             System.out.println("The search keyword entered is : " +keyWord);   
             //Verifying the keyword on UI
             Assert.assertTrue(searchBox.getAttribute("value").equalsIgnoreCase(keyWord));
             driver.quit();
        }
}

Вот TestNG.xml, который будет использоваться для параметризации в TestNG для автоматизации тестирования Selenium.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite thread-count="3" parallel="tests"  name="suite">
  <test name="demo1" >
      <parameter name="keyWord" value="Selenium" />
      <classes>
      <class name="com.lambdatest.ParameterizedClass"/>
    </classes>
  </test> <!-- Test -->
   <test name="demo2" >
    <parameter name="keyWord" value="LambdaTest" />
    <classes>
      <class name="com.lambdatest.ParameterizedClass"/>
    </classes>
  </test> <!-- Test -->
    <parameter name="keyWord" value="Browser Testing" />
    <test name="demo3" >
    <classes>
      <class name="com.lambdatest.ParameterizedClass"/>
    </classes>
  </test> <!-- Test -->
</suite> <!-- Suite -->

Теперь вы можете запустить этот тест, чтобы убедиться, что значение нашего параметра передается в наш метод теста и, следовательно, получены желаемые результаты. Вы можете запустить это, выполнив следующие действия:

Шаг 1: Щелкните правой кнопкой мыши файл testng.xml в проводнике проекта и выберите «Запуск от имени»:

Шаг 2. Выберите «Запуск от имени TestNG Suite», и вы сможете просмотреть отчет или сводку по электронной почте, чтобы просмотреть результаты.

Поэтому в следующий раз, когда нам нужно будет выполнить один и тот же тест для другого тестового значения, вместо того, чтобы копировать и вставлять один и тот же фрагмент кода в несколько файлов, нам просто нужно отредактировать XML-файл, включить дополнительные значения и запустить пакет. Вот и все. Именно таким образом можно эффективно и с минимальными затратами сэкономить время на тестировании Selenium, используя параметризацию в TestNG.

Поможет ли нам параметризация в TestNG с автоматическим тестированием браузера?

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

Сценарий: печать определенного значения браузера путем передачи имени браузера в качестве параметра.

Java-код:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package parameterization;
 import org.testng.annotations.Test;
 import org.testng.annotations.Parameters;
 public class ParameterPass {
         
  @Parameters("browser")
  @Test
  public void test1(String browser) {
          if(browser.equalsIgnoreCase("FF"))
            {
              System.out.println("The browser value is : " +browser);
            }else if(browser.equalsIgnoreCase("Chrome"))
            {
                    System.out.println("The browser value is : " +browser);
                     
            }else if(browser.equalsIgnoreCase("IE"))
            {
                    System.out.println("The browser value is : " +browser);
            }
            else
            {
                    System.out.println("Incorrect browser value passed.");
            }   
  }
}

Testng.xml:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Suite">
  <test name="Firefox Test">
   <parameter name="browser" value="FF"/>
    <classes>
    <class name="parameterization.ParameterPass"/>
    </classes>
  </test>
  
  <test name="IE Test">
   <parameter name="browser" value="IE"/>
    <classes>
    <class name="parameterization.ParameterPass"/>
    </classes>
  </test>
  <test name="Incorrect Browser">
  <parameter name="browser" value="XYZ"/>
    <classes>
    <class name="parameterization.ParameterPass"/>
    </classes>
  </test>
 </suite>

При запуске вышеупомянутого testng xml вы увидите следующий вывод в консоли:

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

Отчет, отправляемый по электронной почте, показывает различные параметры, переданные различным тестам, что упрощает консолидацию результатов

Давайте теперь попробуем передать 2 параметра в наш тест, чтобы понять, как мы можем использовать комбинации параметров для автоматизации тестирования Selenium. Обратите внимание, что независимо от того, сколько параметров вы передадите в свой тест, вы должны принять то же количество параметров в вашем методе теста, что и в правильной последовательности.

Сценарий: печать определенного значения браузера и URL-адреса путем передачи имени браузера и URL-адреса в качестве параметра.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
package parameterization;
import org.testng.annotations.Parameters;
import org.testng.annotations.Test;
 public class ParameterPass_Multiple {
  
        @Parameters({"url","browser"})
        @Test
        public void test1(String url,String browser)
        {
            if(browser.equalsIgnoreCase("FF"))
            {
                    System.out.println("The browser value is : " +browser);
            }
            else if(browser.equalsIgnoreCase("Chrome"))
            {  
                    System.out.println("The browser value is : " +browser);    
            }
            else if(browser.equalsIgnoreCase("IE"))
            {
                    System.out.println("The browser value is : " +browser);
            }
            else
            {
                    System.out.println("Incorrect browser value passed.");
            }
}
}
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Suite">
  <test name="Firefox Test">
   <parameter name="url" value="http://www.google.com"/>
   <parameter name="browser" value="FF"/>
    <classes>
    <class name="parameterization.ParameterPass_Multiple"/>
    </classes>
  </test>
  
  <test name="Chrome Test">
   <parameter name="url" value="http://www.yahoo.com"/>
   <parameter name="browser" value="Chrome"/>
    <classes>
    <class name="parameterization.ParameterPass_Multiple"/>
    </classes>
  </test>
</suite>

Теперь при запуске вышеупомянутого xml ниже генерируется вывод, который печатает оба переданных параметра:

Отчет по электронной почте:

Параметризация в TestNG для сети Selenium

Параметризация — это отличный способ создать аккуратную платформу Test Driven Testing с использованием TestNG. Вам решать, как вы хотите использовать различные типы параметризации в TestNG или даже оба одновременно, если этого требует сценарий использования.

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

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

Например, давайте рассмотрим сценарий, в котором у вас есть тест, который вы хотите запустить в нескольких тестовых средах, чтобы убедиться, что веб-страница является кросс-браузерной. Это типичный пример автоматизированного межбраузерного тестирования, который сейчас является основным требованием почти для каждой организации, которая генерирует любой бизнес через Интернет.

Для запуска теста на LambdaTest Selenium Grid вам необходимо определить объект требуемых возможностей, который инструктирует нашу онлайн-систему Selenium Grid о том, в каких средах вам необходимо запустить тест. Для этого вы можете параметризовать значения для объекта требуемых возможностей. Например, рассмотрим следующий код. Это простой скрипт, который открывает список задач и выполняет некоторые действия. Этот же сценарий выполняется в нескольких средах путем параметризации значений среды требуемых возможностей в файле XML.

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
package com.lambdatest;
 
import java.net.MalformedURLException;
import java.net.URL;
 
import org.openqa.selenium.By;
//import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.testng.Assert;
//import org.testng.annotations.AfterSuite;
import org.testng.annotations.Parameters;
import org.testng.annotations.AfterTest;
//import org.testng.annotations.BeforeSuite;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
 
public class TestNGTodo4 {
 
    private RemoteWebDriver driver;
    private String Status="failed";
 
    @BeforeTest
    @Parameters({ "os", "browser", "version", "build" })
    public void setup( String os, String browser, String version, String build) throws MalformedURLException {
        String username = "mudits";
        String authkey = "kIVQzcwYkSMgZFWoSMxQjcR3ASJo2BIOUQ97GmTwdnPEOFEO2b";
        String hub = "@hub.lambdatest.com/wd/hub";
 
        DesiredCapabilities caps = new DesiredCapabilities();
        caps.setCapability("platform", os);
        caps.setCapability("browserName", browser);
        caps.setCapability("version", version);
        caps.setCapability("build", build);
        caps.setCapability("name", "TestNG-Todo-Script-4");
        caps.setCapability("network", true);
        caps.setCapability("visual", true);
        caps.setCapability("video", true);
        caps.setCapability("console", true);
 
        driver = new RemoteWebDriver(new URL("https://" + username + ":" + authkey + hub), caps);
    }
 
    @Test
    public void basicTest() throws InterruptedException {
        String spanText;
        System.out.println("Loading Url");
         
 
        System.out.println("Checking Box");
        driver.findElement(By.name("todo-1")).click();
         
 
        System.out.println("Checking Another Box");
        driver.findElement(By.name("todo-2")).click();
         
 
        System.out.println("Checking Box");
        driver.findElement(By.name("todo-3")).click();
         
 
        System.out.println("Checking Another Box");
        driver.findElement(By.name("todo-4")).click();
         
 
        driver.findElement(By.id("todotext")).sendKeys(" List Item 6");
        driver.findElement(By.id("addbutton")).click();
         
 
        driver.findElement(By.id("todotext")).sendKeys(" List Item 7");
        driver.findElement(By.id("addbutton")).click();
         
 
        driver.findElement(By.id("todotext")).sendKeys(" List Item 8");
        driver.findElement(By.id("addbutton")).click();
         
 
     
 
        System.out.println("Entering Text");
        driver.findElement(By.id("todotext")).sendKeys("Get Taste of Lambda and Stick to It");
         
 
        driver.findElement(By.id("addbutton")).click();
 
        System.out.println("Checking Another Box");
        driver.findElement(By.name("todo-9")).click();
         
        // Let's also assert that the todo we added is present in the list.
 
        spanText = driver.findElementByXPath("/html/body/div/div/div/ul/li[9]/span").getText();
        Assert.assertEquals("Get Taste of Lambda and Stick to It", spanText);
        Status="passed";
        //Thread.sleep(150);
 
        System.out.println("TestFinished");
 
    }
 
    @AfterTest
    public void tearDown() {
        driver.executeScript("lambda-status=" + Status);
        System.out.println(this.getClass().getName());
        driver.quit();
    }
 
}
 
Here’s the Corresponding XML file
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite thread-count="3" parallel="tests"  name="suite">
  <parameter name="build" value="Demo-TestNG" />
  <test name="demo1" >
      <parameter name="os" value="windows 10" />
      <parameter name="browser" value="chrome" />
      <parameter name="version" value="73" />
      <classes>
      <class name="com.lambdatest.TestNGTodo4"/>
    </classes>
  </test> <!-- Test -->
   <test name="demo2" >
    <parameter name="os" value="windows 8.1" />
    <parameter name="browser" value="firefox" />
    <parameter name="version" value="59" />
    <classes>
      <class name="com.lambdatest.TestNGTodo5"/>
    </classes>
  </test> <!-- Test -->
    <parameter name="os" value="macOS Mojave" />
    <parameter name="browser" value="safari" />
    <parameter name="version" value="12" />
    <test name="demo3" >
    <classes>
      <class name="com.lambdatest.TestNGTodo6"/>
    </classes>
  </test> <!-- Test -->
</suite> <!-- Suite -->

Вы заметили, как я использовал число потоков и параллельное значение в теге Suite для автоматизации тестирования Selenium?

Этот вышеприведенный скрипт будет запускать один и тот же тестовый класс в 3 разных средах, и лучшая часть будет выполняться параллельно. Это означает, что все три теста будут выполняться одновременно, сокращая время выполнения теста в несколько раз. Спасибо Selenium Grid за предоставленную нам возможность использовать параллельное тестирование с Selenium .

Что нужно учитывать

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

⟶ Если вы попытаетесь типизировать значение параметра в testng.xml к соответствующему параметру метода тестирования, возникнет ошибка. Например, если вы указали параметр метода как целое число , но передали значение String в TestNG.xml, вы получите исключение, как показано ниже:

Testng.xml:

Использование аннотации @Optional

Если параметр, который мы определили в нашем методе, отсутствует в testng.xml, то возникнет исключение testNG, и наш тест будет пропущен. Чтобы преодолеть эту ситуацию, мы можем использовать аннотацию @Optional. Давайте сначала посмотрим на синтаксис этого:

1
2
3
@Parameter(“browser”)
@Test
public void paramCheck(@Optional(“OptionalParameter”) String val)   { …. }

Давайте разберемся в этом подробно с примером из этого учебного пособия по TestNG.

Java-код:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
package parameterization;
import org.testng.annotations.Optional;
import org.testng.annotations.Parameters;
import org.testng.annotations.Test;
  
public class optionalParameter {   
        @Parameters("Param One")
        @Test
        public void testOptionOne(String firstParam){
            System.out.println("The first parameter is : " +firstParam);
        }
  
        @Parameters("Param Two")
        @Test
        public void testOptionTwo(@Optional("OptionalParameter")String secondParam){
            System.out.println("The second parameter is : " +secondParam);
        }  
}
01
02
03
04
05
06
07
08
09
10
11
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Suite">
<parameter name="Param One" value="My First Parameter"/>
<parameter name="Param Two" value="My Second Parameter"/>
  <test name="Test">
    <classes>
    <class name="parameterization.optionalParameter"/>
    </classes>
  </test>
</suite>

Запустив вышеупомянутый testng.xml, мы получим простые результаты, в которых будут отображены первый и второй параметры, поскольку оба они были явно объявлены в XML. То же самое показано на выходных изображениях ниже.

Давайте теперь прокомментируем второй параметр из xml и посмотрим, как работает аннотация @Optional:

Новый testng.xml:

01
02
03
04
05
06
07
08
09
10
11
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Suite">
<parameter name="Param One" value="My First Parameter"/>
<!-- <parameter name="Param Two" value="My Second Parameter"/> -->
  <test name="Test">
    <classes>
    <class name="parameterization.optionalParameter"/>
    </classes>
  </test>
</suite>

При запуске этого нового XML мы видим, что необязательный параметр в TestNG был объявлен в печатном методе теста, и нигде не выдается никаких исключений:

⟶ Могут быть сценарии, когда вам нужно протестировать несколько значений параметра, используя testng.xml. Аннотация @Parameters не подходит для этой цели. У нас может быть несколько параметров, но каждый из них может иметь одно значение, что делает наш код многократно используемым. Это больше похоже на файл конфигурации для нашего проекта. Для вас использовать несколько значений для параметра Поставщики данных приходят на помощь.

В следующем разделе этого учебного руководства TestNG будет больше рассказано о поставщиках данных и их использовании в автоматизации тестирования Selenium.

Параметризация в TestNG с использованием провайдеров данных

В предыдущем разделе мы увидели, как мы можем использовать аннотацию @Parameters в нашей среде для получения различных результатов. Теперь, продолжая, мы столкнемся со случаями, когда нам придется использовать тестовые сценарии для нескольких наборов данных. Возможно, нам понадобятся огромные наборы данных для одного выполнения. Этот тип тестирования также называется Data Driven Testing, который может быть удобно реализован аннотацией @DataProvider в нашей среде TestNG.

Давайте сначала посмотрим синтаксис аннотации @DataProvider.

1
2
@DataProvider(name=”testData”)
public Object[ ][ ] TestDataFeed(){

Прежде чем мы начнем использовать его для параметризации в TestNG, вам нужно отметить два момента. Во-первых, @DataProvider имеет только один атрибут ‘ name ‘. Во-вторых, это необязательно, и если вы не укажете его, то имя будет таким же, как имя соответствующего метода.
Этот поставщик данных возвращает объект двумерного массива.

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

Сценарий: откройте google.com в своем браузере и найдите 3 комбинации ключевых слов по отдельности.

Ниже приведены шаги для выполнения этого:

  1. Запустите браузер, чтобы открыть www.google.com
  2. Поиск по первой комбинации ключевых слов.
  3. Получить заголовок страницы.
  4. Повторите шаги, описанные выше, то есть 2 и 3 для комбинации других двух ключевых слов.

Памятник

город

Ворота Индии

Дели

Тадж Махал

Агра

Чар Минар

Хайдарабад

Java-код:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
package dataProvider;
  
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
  
public class Data_Provider {
   
      WebDriver driver;
  
  @Test(dataProvider="searchText")
  public void paramByDataProvider(String monument,String city) throws InterruptedException {
    //Initializing Driver
            System.setProperty("webdriver.gecko.driver", "C:\\geckodriver.exe");
            driver = new FirefoxDriver();
            //Opening search engine
            driver.get("https://google.com");
     WebElement searchBox=driver.findElement(By.name("q"));
     searchBox.sendKeys(monument +" "+city);
     System.out.println("You are trying to search " +monument+ " which is in " +city);
      
     WebElement srchBtn = driver.findElement(By.name("btnK"));
     srchBtn.submit();
     Thread.sleep(3000);
     System.out.println("The page title is: " +driver.getTitle());
      driver.quit();
  }
  
  
  /*Data Provider which returns Object[][] wherein
   *  first column has 'monument' and the second one has 'city'
   **/
  
  @DataProvider(name="searchText")
  public Object[][] getDataProviderData(){
            Object[][] searchWords=new Object[3][2];
            //Enter data into Object Array
            searchWords[0][0]="India Gate";
            searchWords[0][1]="Delhi";
            searchWords[1][0]="Taj Mahal";
            searchWords[1][1]="Agra";
            searchWords[2][0]="Char Minar";
            searchWords[2][1]="Hyderabad";
      return searchWords;
      
  }
}

Для запуска приведенного выше кода мы используем ниже TestNG.xml и запускаем наш тест так же, как мы делали в приведенных выше примерах:

1
2
3
4
5
6
7
8
9
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Suite">
  <test name="Firefox Test">
    <classes>
    <class name="parameterization.Data_provider"/>
    </classes>
  </test>
 </suite> <!-- Suite -->

Мы получили бы вывод, как показано ниже, который суммирует пропущенных поставщиков данных и соответствующие результаты:

Отправляемый по электронной почте отчет:

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

Код Java для класса провайдера данных:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
package dataProvider;
import org.testng.annotations.DataProvider;
 public class DataProviderClass {
    @DataProvider(name="searchText")
      public static Object[][] getDataProviderData(){
                Object[][] searchWords=new Object[3][2];
                //Enter data into Object Array
                searchWords[0][0]="India Gate";
                searchWords[0][1]="Delhi";
                searchWords[1][0]="Taj Mahal";
                searchWords[1][1]="Agra";
                searchWords[2][0]="Char Minar";
                searchWords[2][1]="Hyderabad";
              return searchWords;
              }
}

Код Java для класса, из которого вызывается поставщик данных:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
package dataProvider;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.testng.annotations.Test;
 public class ClassLevelDataProvider {
          WebDriver driver;
 @Test(dataProvider="searchText",dataProviderClass=DataProviderClass.class)
public void paramByDataProvider(String monument,String city) throws InterruptedException {
    //Initializing Driver
            System.setProperty("webdriver.gecko.driver", "C:\\geckodriver.exe");
            driver = new FirefoxDriver();
            //Opening search engine
            driver.get("https://google.com");
     WebElement searchBox=driver.findElement(By.name("q"));
     searchBox.sendKeys(monument +" "+city);
     System.out.println("You are trying to search " +monument+ " which is in " +city);
      
     WebElement srchBtn = driver.findElement(By.name("btnK"));
     srchBtn.submit();
     Thread.sleep(3000);
     System.out.println("The page title is: " +driver.getTitle());
      driver.quit();
}
}

TestNG.xml для запуска вышеуказанного кода:

1
2
3
4
5
6
7
8
9
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Suite">
  <test name="Firefox Test">
    <classes>
    <class name="parameterization.ClassLevelDataProvider"/>
    </classes>
  </test>
  </suite> <!-- Suite -->

При запуске вы можете убедиться, что мы получаем те же результаты, что и раньше. Чтобы понять немного больше о различных условиях, с которыми мы можем столкнуться в нашей автоматизации, важно понять еще несколько примеров использования аннотации провайдера данных с параметрами viz Method и ITestContext .

Пример 1 — Использование параметра метода в TestNG

Что если мы хотим, чтобы один и тот же поставщик данных работал по-разному для разных методов, как в случае, когда мы тестируем разные наборы данных для разных методов тестирования, мы будем использовать параметры метода в TestNG. Давайте рассмотрим пример, который будет следовать следующим шагам:

  • Проверьте, является ли метод именем domesticMonuments
  • Если это так, вернуть один набор значений
  • Если нет, то другой набор значений

Java-код:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
package dataProvider;
import java.lang.reflect.Method;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
public class dataProviders {
        WebDriver driver;
    @BeforeMethod
    public void setUp(){
            //Initializing Driver
                        System.setProperty("webdriver.gecko.driver", "C:\\geckodriver.exe");
                        driver = new FirefoxDriver();
                        //Opening search engine
                        driver.get("https://google.com");
                }
    @AfterMethod
    public void tearDown(){
            driver.quit();
    }
    @Test(dataProvider="destinations")
    public void domesticMonuments(String monument,String city) throws InterruptedException{
            WebElement searchBox=driver.findElement(By.name("q"));
             searchBox.sendKeys(monument +" "+city);
             System.out.println("You are trying to search " +monument+ " which is in " +city);
             WebElement srchBtn = driver.findElement(By.name("btnK"));
             srchBtn.submit();
             Thread.sleep(3000);
             System.out.println("The page title is: " +driver.getTitle());
                }
    @Test(dataProvider="destinations")
    public void intlDestinations(String location) throws InterruptedException{
            WebElement searchBox=driver.findElement(By.name("q"));
            searchBox.sendKeys(location);
            System.out.println("You are trying to search : " +location);
            WebElement srchBtn = driver.findElement(By.name("btnK"));
             srchBtn.submit();
             Thread.sleep(3000);
             System.out.println("The page title is: " +driver.getTitle());  
    }
    @DataProvider(name="destinations")
      public Object[][] getDataProviderData(Method m){
            if(m.getName().equalsIgnoreCase("domesticMonuments")){
                return new Object[][]{
                        { "India Gate", "Delhi" },
                        { "Taj Mahal", "Agra" },
                        { "Char Minar", "Hyderabad" }
                };
                }
            else{
                return new Object[][]{
                        {"Paris"},
                        {"Cairo"},
                        {"Washington"}
                };
            }   
      }
}

Testng.XML для запуска приведенного выше кода:

1
2
3
4
5
6
7
8
9
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Suite" >
  <test name="Firefox Test">
    <classes>
    <class name="parameterization.dataProviders"/>
    </classes>
  </test>
  </suite>

Результаты запуска xml будут такими, как ниже, где вы сможете увидеть подробную информацию об используемых поставщиках данных.

Пример 2 — Использование параметра ITestContext в TestNG

Предположим, мои методы испытаний назначены разным группам, и мне нужно использовать разные данные испытаний для разных групп. В таком случае мы можем использовать параметр ITestContext с нашей аннотацией провайдера данных. Давайте посмотрим на пример того же.

Java-код:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
package dataProvider;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.testng.ITestContext;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
  
public class ITestContext_DP {
    WebDriver driver;
    @BeforeMethod(groups={"One","Two"})
    public void setUp(){
            //Initializing Driver
                        System.setProperty("webdriver.gecko.driver", "C:\\geckodriver.exe");
                        driver = new FirefoxDriver();
                        //Opening search engine
                        driver.get("https://google.com");
                }
    @AfterMethod(groups={"One","Two"})
    public void tearDown(){
            driver.quit();
    }
     
    @Test(dataProvider="searchKey" , groups="One")
    public void testMethodOne(String monument,String city) throws InterruptedException{
            WebElement searchBox=driver.findElement(By.name("q"));
             searchBox.sendKeys(monument +" "+city);
             System.out.println("You are trying to search " +monument+ " which is in " +city);
              
             WebElement srchBtn = driver.findElement(By.name("btnK"));
             srchBtn.submit();
             Thread.sleep(3000);
             System.out.println("The page title is: " +driver.getTitle());
    }  
    @Test(dataProvider="searchKey" , groups="Two")
    public void testMethodTwo(String location) throws InterruptedException{
  
            WebElement searchBox=driver.findElement(By.name("q"));
            searchBox.sendKeys(location);
            System.out.println("You are trying to search : " +location);
            WebElement srchBtn = driver.findElement(By.name("btnK"));
             srchBtn.submit();
             Thread.sleep(3000);
             System.out.println("The page title is: " +driver.getTitle());  
    }
    @DataProvider(name="searchKey")
      public Object[][] getDataProviderData(ITestContext c){
            Object[][] grpArr = null;
            for (String grp : c.getIncludedGroups()){
                if(grp.equalsIgnoreCase("One")){
                        grpArr = new Object[][]{
                            { "India Gate", "Delhi" },
                            { "Taj Mahal", "Agra" },
                            { "Char Minar", "Hyderabad" }
                        };
                        break;
                }
                else if(grp.equalsIgnoreCase("Two")){
                        grpArr = new Object[][]{
                            {"Paris"},
                            {"Cairo"},
                            {"Washington"}
                        };
                }
            }  
            return grpArr;
      }
}

Чтобы вызвать этот класс testNG, вы можете использовать ниже xml, который будет запускать два набора тестов, основанных на разных группах.

Testng.xml:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?xml version="1.0" encoding="UTF-8"?>
<suite name="Suite" >
  <test name="First DP Run">
    <groups>
        <run>
            <include name = "One" />
        </run>
    </groups>
    <classes>
    <class name="dataProvider.ITestContext_DP"/>
    </classes>
  </test>
  <test name="Second DP Run">
    <groups>
        <run>
            <include name = "Two" />
        </run>
    </groups>
    <classes>
    <class name="dataProvider.ITestContext_DP"/>
    </classes>
  </test>
 </suite>

Запуск вышеуказанного xml даст результаты, как показано ниже:

Вывод

Параметризация в TestNG позволяет более эффективно выполнять управляемое данными тестирование. Объявляя параметры, вам не нужно будет писать несколько сценариев автоматизации тестирования для разных входов теста одного набора тестов, что облегчит вам поддержку кода автоматизации тестирования. Я надеюсь, что это руководство TestNG помогло вам использовать ваши сценарии автоматизации тестирования Selenium. Параметризация в TestNG для ваших сценариев тестирования автоматизации Selenium может быть выполнена с использованием либо DataProvider, либо аннотации Parameter с TestNG.xml. Мы говорили о параметризации в обоих направлениях с примерами, очень подробно. Мы поняли, что DataProvider дополнительно предлагает 2 параметра, т.е. Method & ITestContext . Теперь вы можете запустить свои сценарии автоматизации тестирования, используя параметризацию в TestNG для вашего следующего проекта. Дайте мне знать ваши мысли об этом учебнике TestNG в разделе комментариев ниже. Если у вас есть какие-либо сомнения или вопросы, не стесняйтесь их публиковать. Ура и счастливого тестирования!

См. Оригинальную статью здесь: Параметризация в TestNG — DataProvider и TestNG XML (с примерами)

Мнения, высказанные участниками Java Code Geeks, являются их собственными.