测试自动化或俗称的自动化测试并不像听起来那样简单。 必须考虑所有可能的用户交互的所有排列和组合,并且在此基础上,您将必须创建测试脚本以通过多种浏览器和OS组合来验证Web应用程序。 这就是参数化在Selenium自动化测试中起关键作用的地方。 在此TestNG教程中,我将向您展示如何在TestNG中执行参数化以进行Selenium自动化测试。
Why Do We Parameterize?
在现实世界中进行Web UI测试时,我们希望我们的网站或Web应用程序可以在各种输入下正常工作,并且实际上不可能仅凭一个数据集来验证我们的方案。 因此,当暴露给浏览器和OS的不同数据集或不同组合时,我们确保应用程序能够按预期运行。 多个测试组合意味着多个输入值。
现在,您不能每次都在测试自动化脚本中对测试值进行硬编码,否则,进行一项更改将需要您编辑许多测试自动化脚本。 在那里,出现了TestNG或其他参数的参数化,而我们对Selenium自动化测试脚本进行参数化的原因是,在运行时为Web应用程序提供了不同的数据集。
How Do We Perform Parameterization? And Why Use TestNG?
如果您的应用程序涉及输入不同类型的用户交互,则必须进行参数化。 我们可以根据所使用的框架对自动化脚本进行参数化,例如,用于硒自动化测试的TestNG框架中的参数化。 我们可以考虑使用excel文件来获取数据集,然后在自动化脚本中使用它,但是随着我们增强自动化套件,有必要使用更强大的测试自动化框架(如TestNG)来以更强大的方式涵盖广泛的测试 。 在本文中,我们将主要关注TestNG中的参数化,在TestNG中可以实现的方法以及如何在Selenium自动化测试脚本中编写这些参数。 首先让我们开始理解TestNG中不同类型的参数化,以及如何实现相同的功能。
Types of Parameterization in TestNG
因此,首先我们可以通过两种方式在TestNG中实现参数化。
- 使用“参数注释”和TestNG XML文件。
- 使用“ DataProvider批注”。
Parameterization In TestNG Using @Parameters Annotation & XML file
首先让我们看看在类中编写参数注释的简单语法:@Parameter({“参数名称”})
请注意,我们在注释中也可以使用多个参数,可以这样编写:@Parameters({“ param1”,“ param2”,“ param3”})
截至目前,“参数”的作用域仅限于“套件”或“测试”标签testng。xml文件。 如果在Suite和Test中都传递了相同的参数值,则优先级将赋予Test标记中传递的参数值。
在继续进行参数化示例之前,我们需要了解在TestNG中使用参数化对Selenium自动化测试活动有什么好处。 考虑一种在Google之类的搜索引擎中搜索某些关键字的方案。 我们将必须为每个关键字编写相同的代码行才能获得不同的结果,但这不是可行的方法。 这就是TestNG或Selenium的任何其他测试自动化框架中的参数化出现的地方。 使用TestNG中的参数化功能,您可以将这些关键字作为不同的参数传递给testng.xml并添加@参数Selenium自动化测试套件中的注解。 让我们以示例的形式看一下。
场景:在浏览器中打开谷歌.com并分别搜索3个关键字
要完成此方案,以下是我们的脚本必须执行的详细步骤:
- Launch the browser和open www.google.com
- Add the first keyword as input in the search box and hit search.
- 验证UI上的输入值是否与测试数据相同.
- 对其他2个关键字重复上述两个步骤.
下面的代码显示了如何在TestNG中不进行参数化的情况下做到这一点。
包参数化;
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;导入org.testng.annotations.Test;
public class WithoutParameter {
WebDriver driver;
@Test
public void noParam(){
//Declaring our first 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();
} }
为了传递其他2个关键字,我们必须再次编写同一段代码,并为字符串“keyWord’,这将导致冗长且重复的代码。 而且,将来,如果您必须测试更多的关键字值,就必须编写更多的测试。
现在让我们通过在testng.xml中绕过这些关键字作为参数并添加来简化问题@参数测试中的注释。
Java代码:
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;导入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,将用于在Selenium自动化测试的TestNG中执行参数化。
<?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文件,包含更多值并运行套件即可。 而已。 这就是通过利用TestNG中的参数设置来实现Selenium自动化测试的效率和节省时间的方式。
Would Parameterization In TestNG Help Us With Automated Browser Testing?
到目前为止,在此用于参数化的TestNG教程中,您可能已经通过上一节中说明的示例认识到了Parameters的重要性。 现在,您可能已经在考虑将参数化合并到TestNG脚本中以进行自动浏览器测试的方法。 让我帮助您从一个非常常见的场景开始,在这个场景中我们需要在多个浏览器上执行测试,让我们看看如何利用参数来执行自动化的浏览器测试。
场景:通过将浏览器名称作为参数传递来打印特定的浏览器值。
Java代码:
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:
<?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自动化测试。 请注意,无论传递给测试的参数数量如何,您都需要在测试方法中接受相同数量的参数,而且顺序也要正确。
场景: Printing a specific browser & URL value by passing the browser name as well as the URL as a parameter.
package parameterization;
import org.testng.annotations.Parameters;
import org.testng.annotations.Test;
公共类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.");
}
}
}
<?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时,将生成以下输出,其中将输出已传递的两个参数:
电子邮件报告:
Parameterization In TestNG For An Online Selenium Grid
参数化是使用TestNG构建简洁的“测试驱动测试”框架的一种巧妙方法。 由您决定如何在TestNG中利用不同类型的参数化,或者在用例需要时同时利用两者。
下一个要回答的问题是,TestNG中的参数化是否可以与LambdaTest提供的包含2000多种实际浏览器的在线Selenium Grid一起使用?
是的,它确实! 实际上,TestNG或任何其他框架中的参数化被认为是在多个不同的测试环境上并行运行测试的最佳方法之一,尤其是在您必须定期更改要测试的测试环境的情况下。
例如,假设有一个要在多个测试环境上运行的测试,以确保该网页与跨浏览器兼容。 这是自动跨浏览器测试的一个典型示例,现已成为几乎每个通过网络开展业务的组织的主要要求。
要在LambdaTest Selenium Grid上运行测试,您需要定义所需的功能对象,该对象指示我们的在线Selenium Grid有关您需要在哪些环境上运行测试的知识。 为此,您可以参数化所需功能对象的值。 例如,考虑以下代码。 这是一个简单的脚本,可打开待办事项列表并执行一些操作。 通过在XML文件中参数化所需功能环境值,可以在多个环境中运行同一脚本。
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");
driver.get("https://4dvanceboy.github.io/lambdatest/todo.html");
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个不同的环境中运行相同的测试类,而最好的部分是它们将并行运行. 这意味着所有三个测试将同时执行,从而将您的测试执行时间缩短了几倍. Thanks to Selenium Grid for allowing us to leverage parallel testing with Selenium.
Things to consider
在参加完此TestNG教程之后,到目前为止,您必须对在下一个项目中使用参数进行Selenium自动化测试感到信心满满,也许有些激动,但要花一会儿时间。 在使用@Parameters批注时,需要注意几点。
⟶如果尝试将testng.xml中的参数值类型转换为相应的测试方法参数,则将引发错误。 例如,如果您将方法参数指定为整数,但是您通过了String在TestNG.xml中的值,您将获得以下异常:
Testng.xml:
⟶使用@Optional批注
如果我们在方法中定义的参数未出现在testng.xml中,则将出现testNG异常,并且测试将跳过。 为了克服这种情况,我们可以使用@Optional注释。 首先让我们看一下它的语法:
@Parameter(“browser”)
@Test
public void paramCheck(@Optional(“OptionalParameter”) String val) { …. }
让我们通过此TestNG教程中的示例深入了解这一点。
Java代码:
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);
}
}
Testng.xml:
<?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>
运行上述testng.xml时,我们将获得简单的结果,其中将显示第一个和第二个参数,因为这两个参数均已在XML中明确声明。 在下面的输出图像中也显示了相同的内容。
现在让我们对xml中的第二个参数进行注释,并查看@Optional注释的工作方式:
新的testng.xml:
<?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中的Optional参数已在现在正在打印的测试方法中声明,并且不会在任何地方引发异常:
may在某些情况下,您需要使用testng.xml测试参数的多个值。 @Parameters注释不符合目的。 我们可以有许多参数,但是每个参数都可以有一个值,从而使我们的代码可重用。 它更像我们项目的配置文件。 您可以使用多个值作为参数来使用数据提供程序。
该TestNG教程的下一部分将详细讨论数据提供程序及其在Selenium自动化测试中的用法。
Parameterization In TestNG Using Data Providers
在上面的部分中,我们看到了如何在框架中使用@Parameters批注来获得各种结果。 现在,在继续进行过程中,我们将遇到必须对多组数据使用测试脚本的情况。 我们可能需要在一次执行中使用庞大的数据集。 这种类型的测试也称为数据驱动测试,可以通过我们的TestNG框架中的@DataProvider注释方便地实现。
现在让我们首先查看@DataProvider批注的语法。
@DataProvider(name=”testData”)
在我们开始在TestNG中使用它进行参数化之前,需要注意两点,首先,@DataProvider只有一个属性,“name’。 其次,它是可选的,如果您未指定它,则该名称将与相应的方法名称相同。
此数据提供程序返回二维数组对象。
让我们尝试通过一个简单的示例来理解这一点,在该示例中,我们尝试使用数据提供程序传递纪念碑和城市名称。 您可以进一步将此示例用作使用其他电子邮件ID和密码登录Gmail或Facebook的基础。
场景:在浏览器中打开google.com,然后分别搜索3个关键字组合。
以下是执行此操作的步骤:
- Launch the browser to open www.google.com
- Search the first keyword combination.
- 获取页面标题.
- 重复以上步骤,我.e. 2 & 3 for the other 2 keywords combination.
Java代码:
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下面使用并像在上面的示例中一样进行测试:
<?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代码:
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代码:
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运行上面的代码:
<?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的Data Provider注释的示例。方法 and ITestContext.
Example 1 – Using 方法 Parameter in TestNG
如果我们希望同一个数据提供者为不同的方法工作而不同,例如在针对不同的测试方法测试不同的数据集的情况下,我们将使用methodTestNG中的参数。 让我们看一个遵循以下步骤的示例:
- 检查方法名称是否为国内
- 如果是,则返回一组值
- 如果不是,那么另一套价值
Java代码:
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运行上面的代码:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
运行xml的结果如下所示,您将能够看到所使用的数据提供者的详细信息。
Example 2 – Using ITestContext Parameter in TestNG
假设我的测试方法分配给了不同的组,并且我需要对不同的组使用不同的测试数据。 在这种情况下,我们可以使用ITestContext参数与我们的数据提供程序注释一起使用。 让我们看一个相同的例子。
Java代码:
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:
<?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将产生如下结果:
Conclusion
TestNG中的参数化允许您以更有效的方式执行数据驱动的测试。 通过声明参数,您不必为单个测试套件的不同测试输入编写多个测试自动化脚本,从而使您更轻松地维护测试自动化代码。 我希望这个TestNG教程能够帮助您利用Selenium自动化测试脚本。 您可以使用DataProvider或带有TestNG.xml的Parameter批注来完成Selenium自动化测试脚本的TestNG中的参数化。 我们通过示例详细讨论了两种方式的参数化。 我们意识到DataProvider进一步提供了2个参数,即Method & ITestContext。 现在,您可以使用TestNG中的参数化为下一个项目启动测试自动化脚本。 在下面的评论部分中,让我知道您对此TestNG教程的想法。 如果您有任何疑问或疑问,也可以随时发布。 祝您测试愉快!