TestNG是CédricBeust创建的测试框架 ,有助于满足我们的许多测试需求。 它被广泛用于硒中。 想知道NG代表什么? 好吧,它指的是“下一代” 。 TestNG与Junit相似,但在控制程序的执行流程方面更强大。 作为框架的本质,我们倾向于使测试更加结构化,并通过使用TestNG提供更好的验证点。
TestNG的一些值得注意的功能是:
- 功能强大且种类繁多的注释可支持您的测试用例。
- 帮助执行并行测试,相关方法测试。
- 通过TestNG.xml文件或通过数据提供者概念通过多组数据运行测试的灵活性。
- 测试用例可以根据需要进行分组并确定优先级。
- 提供对HTML报告的访问,并且可以通过各种插件进行自定义。
- 可以跨测试生成测试日志。
- 可以轻松地与eclipse,Maven,Jenkins等集成。
TestNG程序的基本处理流程包括以下步骤:

因此,在转到TestNG for Selenium中的注释之前,最好先参考设置TestNG所需的先决条件。
先决条件
- Java开发套件
- 设置Eclipse或任何其他IDE。
- 在Eclipse或任何其他IDE中安装TestNG。
注意:注释只能与Java 1.5或更高版本一起使用。
如果您不熟悉TestNG框架,请按照我们的指南使用TestNG运行您的第一个自动化脚本 。
在云网格上运行TestNG Selenium脚本
那么,什么是注释?
注释是提供有关类或方法的其他信息的标签。 它由“ @”前缀表示。 TestNG使用这些注释来帮助创建一个健壮的框架。 让我们来看看用于用Selenium进行自动化测试的TestNG的这些注释。
@测试
主要业务逻辑所在的TestNG框架中最重要的注释。 所有要自动化的功能都保留在@Test批注方法中。 它具有各种属性,可以根据这些属性来重新构造和执行该方法。
以下验证url的代码段示例:
@Test
public void testCurrentUrl() throws InterruptedException
{
driver.findElement(By.xpath("//*[@id='app']/header/aside/ul/li[4]/a")).click();
String currentUrl= driver.getCurrentUrl();
assertEquals(current_url, "https://automation.lambdatest.com/timeline/?viewType=build&page=1", "url did not matched");
}
@BeforeTest
该注释在类中的第一个@Test注释方法之前运行。 您可以在TestNG for Selenium中使用此注释来设置浏览器配置文件首选项,例如以最大化模式自动打开浏览器,为浏览器设置自己的自定义配置文件等。
下面是确保测试器以最大化模式打开的BeforeTest方法的代码片段:
@BeforeTest
public void profileSetup()
{
driver.manage().window().maximize();
}
@AfterTest
TestNG中的此批注在您属于该类的所有测试方法运行后运行。 这是一个有用的注释,在向您的利益相关者报告自动化结果方面非常有用。 您可以使用此批注生成测试报告,并通过电子邮件将其分享给您的涉众。
下面的代码段示例:
@AfterTest
public void reportReady()
{
System.out.println("Report is ready to be shared, with screenshots of tests");
}
@BeforeMethod
TestNG中的此注释在每个@test注释方法之前运行。 您可以在执行测试之前使用它来签出数据库连接,或者可以说@test带注释的方法已经测试了不同的功能,该方法要求用户登录某个类。 在这种情况下,您也可以将您的登录代码放入@BeforeMethod批注方法中。
下面的代码段是一个示例,显示了LambdaTest平台的登录功能:
@BeforeMethod
public void checkLogin()
{
driver.get("https://accounts.lambdatest.com/login");
driver.findElement(By.xpath("//input[@name='email']")).sendKeys("sadhvisingh24@gmail.com");
driver.findElement(By.xpath("//input[@name='password']")).sendKeys("XXXXX");
driver.findElement(By.xpath("//*[@id='app']/section/form/div/div/button")).click();
}
@AfterMethod
该注释在每个@test注释方法之后运行。 此批注可用于截取针对测试运行而运行的每个测试方法的屏幕截图。
下面的代码片段指示在Selenium的TestNG中的@AfterTest批注中截取的屏幕截图:
@AfterMethod
public void screenShot() throws IOException
{
TakesScreenshot scr= ((TakesScreenshot)driver);
File file1= scr.getScreenshotAs(OutputType.FILE);
FileUtils.copyFile(file1, new File("C:\\Users\\navyug\\workspace\\QAPractise\\test-output\\test1.PNG"));
}
@课前
该注释在当前类的第一个测试方法之前运行。 此注释可用于设置浏览器属性,初始化驱动程序,使用所需的URL打开浏览器等。
以下是BeforeClass的代码段:
@BeforeClass
public void appSetup()
{
driver.get(url);
}
@下课以后
该注释在当前类中的最后一个测试方法之后运行。 TestNG中的此批注可用于在测试过程中执行清理活动,例如关闭驱动程序等
以下是显示已执行的关闭活动的代码片段示例:
@AfterClass
public void closeUp()
{
driver.close();
}
@BeforeSuite
一个套件可以包含多个类,此批注在所有类的所有测试方法之前运行。 该注释标记了执行的入口点。 TestNG中的@BeforeSuite批注可用于执行所需的通用功能,例如设置和启动Selenium驱动程序或远程Web驱动程序等。
TestNG中@BeforeSuite批注的示例,显示了设置驱动程序的代码片段:
@BeforeSuite
public void setUp()
{
System.setProperty("webdriver.chrome.driver", "path to chrome driver");
driver=new ChromeDriver();
}
@AfterSuite
TestNG运行中的此注释发布了所有类的所有测试方法。 当您有多个运行中的类(例如,关闭驱动程序等)时,此注释可用于在完成测试之前清理过程。
下面是TestNG for Selenium中@AfterSuite批注的代码片段:
@AfterSuite
public void cleanUp()
{
System.out.println("All close up activities completed");
}
@BeforeGroups
TestNG通过@Test批注中使用的属性组帮助测试人员将一组测试按组创建。 例如,如果您希望将与用户管理相关的所有相似功能组合在一起,则可以将所有测试(例如仪表板,配置文件,事务等)标记为一个组,称为“ user_management”。 TestNG中的@BeforeGroups批注有助于在指定的组之前先运行定义的测试。 如果小组专注于单个功能,如上面的示例中所述,则可以使用此注释。 BeforeGroup批注可以包含登录功能,该功能必须在用户仪表板,用户配置文件等任何其他方法之前运行。
Selenium的TestNG中@BeforeGroups批注的代码片段示例:
@BeforeGroups("urlValidation")
public void setUpSecurity() {
System.out.println("url validation test starting");
}
@AfterGroups
TestNG中的此批注在指定组的所有测试方法执行后运行。
Selenium的TestNG中@AfterGroups批注的代码片段示例:
@AfterGroups("urlValidation")
public void tearDownSecurity() {
System.out.println("url validation test finished");
}
The below code displays an example of all annotations used along with TestNG report respectively:
import static org.testng.Assert.assertEquals;
import java.io.File;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
import org.apache.commons.io.FileUtils;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.testng.annotations.AfterClass;
import org.testng.annotations.AfterGroups;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.AfterSuite;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.BeforeGroups;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.BeforeSuite;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
public class AnnotationsTestNG {
public WebDriver driver;
public String url="https://www.lambdatest.com/";
@BeforeSuite
public void setUp()
{
System.setProperty("webdriver.chrome.driver", "C:\\Users\\navyug\\workspace\\QAPractise\\src\\ChromeDriver\\chromedriver.exe");
driver=new ChromeDriver();
driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);
System.out.println("The setup process is completed");
}
@BeforeTest
public void profileSetup()
{
driver.manage().window().maximize();
System.out.println("The profile setup process is completed");
}
@BeforeClass
public void appSetup()
{
driver.get(url);
System.out.println("The app setup process is completed");
}
@BeforeMethod
public void checkLogin()
{
driver.get("https://accounts.lambdatest.com/login");
driver.findElement(By.xpath("//input[@name='email']")).sendKeys("sadhvisingh24@gmail.com");
driver.findElement(By.xpath("//input[@name='password']")).sendKeys("activa9049");
driver.findElement(By.xpath("//*[@id='app']/section/form/div/div/button")).click();
System.out.println("The login process on lamdatest is completed");
}
@Test(groups="urlValidation")
public void testCurrentUrl() throws InterruptedException
{
driver.findElement(By.xpath("//*[@id='app']/header/aside/ul/li[4]/a")).click();
Thread.sleep(6000);
String currentUrl= driver.getCurrentUrl();
assertEquals(currentUrl, "https://automation.lambdatest.com/timeline/?viewType=build&page=1", "url did not matched");
System.out.println("The url validation test is completed");
}
@AfterMethod
public void screenShot() throws IOException
{
TakesScreenshot scr= ((TakesScreenshot)driver);
File file1= scr.getScreenshotAs(OutputType.FILE);
FileUtils.copyFile(file1, new File("C:\\Users\\navyug\\workspace\\QAPractise\\test-output\\test1.PNG"));
System.out.println("Screenshot of the test is taken");
}
@AfterClass
public void closeUp()
{
driver.close();
System.out.println("The close_up process is completed");
}
@AfterTest
public void reportReady()
{
System.out.println("Report is ready to be shared, with screenshots of tests");
}
@AfterSuite
public void cleanUp()
{
System.out.println("All close up activities completed");
}
@BeforeGroups("urlValidation")
public void setUpSecurity() {
System.out.println("url validation test starting");
}
@AfterGroups("urlValidation")
public void tearDownSecurity() {
System.out.println("url validation test finished");
}
}
TestNG报告:

控制台输出:

硒中TestNG中注释的执行顺序
上述所有注释均按以下顺序在运行时执行:
- 之前的套房
- 测试前
- 课前
- 团体前
- 方法前
- 测试
- 后方法
- 后组
- 下课以后
- 事后测试
- AfterSuite
这是这些注释的基本工作流程的图像:

TestNG中与注释一起使用的属性
TestNG中的这些测试注释具有可用于我们的测试方法的多个属性。 这些属性还有助于定义我们的测试,并有助于提供在TestNG类中使用的不同测试方法的执行流程方面的清晰度。 在下面列出它们:
- 说明:它定义了测试方法。 可以通过描述定义方法的作用。 例如,@
@Test(description=”this test validates the login functionality”)
。 - alwaysRun:此属性与测试方法一起使用时,即使该方法所依赖的参数失败,也可以确保它始终运行而不管事实。 当该值设置为true时,此方法将始终执行。 例如,@Test(alwaysRun = true)。
- dataProvider:此属性设置为从带数据提供者注释的测试向使用此属性提供的测试提供数据。 例如,假设您打算在多个跨浏览器上运行测试,其中编写了一个带数据提供者注释的测试,其中包含浏览器及其相应版本的多个输入。 在这种情况下,包含此属性的测试将使用这些数据输入在多个浏览器上运行测试。 相同的语法是@Test(dataProvider =“跨浏览器测试”)。
- dependsOnMethods:此属性提供执行流程的详细信息,其中仅当执行属性中提到的依赖方法时,才执行测试。 如果该方法所依赖的测试失败或未执行,则从执行中跳过该测试。 例如,@Test(dependsOnmethod =“ Login”)。
- 组:此属性有助于将专注于单个功能的测试方法分组。 例如@Test(groups =“ Payment_Module”)。 当一个人可以选择在执行周期中忽略几个组并选择其他组时,此属性还有助于延长运行时间。 所有需要做的就是在include标记中提及TestNG.xml文件中的包含组,而可以使用xml文件中的exclude标记来定义被排除的组。
- dependsOnGroups:此属性按排序规则执行上述两个属性功能,即,使用属性“ dependsOn”定义已定义的组来定义测试方法。 一旦运行了那组测试,就只能发布该带注释的方法将要执行的信息。 例如,@Test(dependsOnMethods =“ Payment_Module”)。
- 优先级:此属性有助于我们定义测试方法的优先级。 当TestNG执行@Test带注释的方法时,它可能以随机顺序执行。 在您希望您的@Test带注释的方法按所需顺序运行的情况下,可以使用priority属性。 所有测试方法的默认优先级均为0。升序排列的优先级首先被安排执行,例如@Test(priority = 1),@ Test(priority = 2),在这种情况下,将执行优先级等于1的测试首先,然后是优先级为2的测试。
- enabled:当您打算忽略特定的测试方法并且不想执行它时,此属性会出现。 您需要做的就是将此属性设置为false。 例如,@Test(enabled = false)。
- 超时:此属性有助于定义特定测试应执行的时间,如果超出该属性定义的时间,则测试方法将终止并失败,并带有标记为org.testng.internal.thread.ThreadTimeoutException的异常。 例如,@ Test(timeOut = 500)。 请注意,指定的时间以毫秒为单位。
- InvocationCount:此属性的工作原理与循环类似。 基于测试方法中设置的属性,它将多次执行该方法。 例如,@Test(invocationCount = 5),它将执行5次测试。
- InvocationTimeOut:此属性与上面的invocationCount属性一起使用。 基于此属性的设置值以及invocationCount,这可以确保测试在由invocationTimeOut属性设置的定义时间内运行根据invocationCount指定的次数。 例如,@Test(invocationCount = 5,invocationTimeOut = 20)。
- ExpectedExceptions:此属性有助于处理测试方法预期引发的异常。 如果属性中定义的一个被测试方法设置并抛出,则传递该属性,否则属性中未声明并由测试方法抛出的任何其他异常将使测试方法失败。 例如,@Test(expectedExceptions = {ArithmeticException.class})。
上面定义的是与TestNG for Selenium中的注释一起使用的属性。 下面的代码片段展示了上述属性的用法:
import static org.testng.Assert.assertEquals;
import java.io.File;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
import org.apache.commons.io.FileUtils;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.testng.annotations.AfterClass;
import org.testng.annotations.AfterGroups;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.AfterSuite;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.BeforeGroups;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.BeforeSuite;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
public class AnnotationsTest {
public WebDriver driver;
public String url="https://www.lambdatest.com/";
@BeforeSuite
public void setUp()
{
System.setProperty("webdriver.chrome.driver", "C:\\Users\\navyug\\workspace\\QAPractise\\src\\ChromeDriver\\chromedriver.exe");
driver=new ChromeDriver();
System.out.println("The setup process is completed");
}
@BeforeTest
public void profileSetup()
{
driver.manage().window().maximize();
System.out.println("The profile setup process is completed");
}
@BeforeClass
public void appSetup()
{
driver.get(url);
System.out.println("The app setup process is completed");
}
@Test(priority=2)
public void checkLogin()
{
driver.get("https://accounts.lambdatest.com/login");
driver.findElement(By.xpath("//input[@name='email']")).sendKeys("sadhvisingh24@gmail.com");
driver.findElement(By.xpath("//input[@name='password']")).sendKeys("xxxxx");
driver.findElement(By.xpath("//*[@id='app']/section/form/div/div/button")).click();
System.out.println("The login process on lamdatest is completed");
}
@Test(priority=0 ,description= "this test validates the sign-up test")
public void signUp() throws InterruptedException
{
WebElement link= driver.findElement(By.xpath("//a[text()='Free Sign Up']"));
link.click();
WebElement organization=driver.findElement(By.xpath("//input[@name='organization_name']"));
organization.sendKeys("LambdaTest");
WebElement firstName=driver.findElement(By.xpath("//input[@name='name']"));
firstName.sendKeys("Test");
WebElement email=driver.findElement(By.xpath("//input[@name='email']"));
email.sendKeys("User622@gmail.com");
WebElement password=driver.findElement(By.xpath("//input[@name='password']"));
password.sendKeys("TestUser123");
WebElement phoneNumber=driver.findElement(By.xpath("//input[@name='phone']"));
phoneNumber.sendKeys("9412262090");
WebElement termsOfService=driver.findElement(By.xpath("//input[@name='terms_of_service']"));
termsOfService.click();
WebElement button=driver.findElement(By.xpath("//button[text()='Signup']"));
button.click();
}
@Test(priority=3, alwaysRun= true, dependsOnMethods="check_login", description="this test validates the URL post logging in" , groups="url_validation")
public void testCurrentUrl() throws InterruptedException
{
driver.findElement(By.xpath("//*[@id='app']/header/aside/ul/li[4]/a")).click();
String currentUrl= driver.getCurrentUrl();
assertEquals(current_url, "https://automation.lambdatest.com/timeline/?viewType=build&page=1", "url did not matched");
System.out.println("The url validation test is completed");
}
@Test(priority=1, description = "this test validates the logout functionality" ,timeOut= 25000)
public void logout() throws InterruptedException
{
Thread.sleep(6500);
driver.findElement(By.xpath("//*[@id='userName']")).click();
driver.findElement(By.xpath("//*[@id='navbarSupportedContent']/ul[2]/li/div/a[5]")).click();
}
@Test(enabled=false)
public void skipMethod()
{
System.out.println("this method will be skipped from the test run using the attribute enabled=false");
}
@Test(priority=6,invocationCount =5,invocationTimeOut = 20)
public void invocationcountShowCaseMethod()
{
System.out.println("this method will be executed by 5 times");
}
@AfterMethod()
public void screenshot() throws IOException
{
TakesScreenshot scr= ((TakesScreenshot)driver);
File file1= scr.getScreenshotAs(OutputType.FILE);
FileUtils.copyFile(file1, new File("C:\\Users\\navyug\\workspace\\QAPractise\\test-output\\test1.PNG"));
System.out.println("Screenshot of the test is taken");
}
@AfterClass
public void closeUp()
{
driver.close();
System.out.println("The close_up process is completed");
}
@AfterTest
public void reportReady()
{
System.out.println("Report is ready to be shared, with screenshots of tests");
}
@AfterSuite
public void cleanUp()
{
System.out.println("All close up activities completed");
}
@BeforeGroups("urlValidation")
public void setUpSecurity() {
System.out.println("url validation test starting");
}
@AfterGroups("urlValidation")
public void tearDownSecurity() {
System.out.println("url validation test finished");
}
}
控制台输出:

TestNG报告:

TestNG中用于预期目的的注释
除了上面定义的注释以外,还有更多注释,这些注释仅用于所需目的。
@DataProvider
该带注释的方法用于向定义了dataProvider属性的测试方法提供数据。 此带注释的方法有助于创建一个数据驱动的框架,在该框架中可以提供多组输入值,这些输入值将返回2D数组或对象。 TestNG中的@DataProvider批注带有两个属性。
- 名称-此属性用于为数据提供者提供名称。 如果未设置,则默认为所提供方法的名称。
- 并行-这是一个属性,可帮助您在不同数据变化的情况下并行运行测试。 此属性是使TestNG对Junit更加强大的原因之一。 其默认值为false。
下面的代码段指示使用@DataProvider批注,并为其设置了名称和parallel属性。
@DataProvider(name="SetEnvironment", parallel=true)
public Object[][] getData(){
Object[][] browserProperty = new Object[][]{
{Platform.WIN8, "chrome", "70.0"},
{Platform.WIN8, "chrome", "71.0"}
};
return browserProperty;
}
@厂
此批注有助于通过单个测试类运行多个测试类。 它基本上可以动态定义和创建测试。
下面的代码片段指示使用@Factory批注来帮助调用测试方法类。
package ChromeDriver;
import org.testng.annotations.Test;
public class FactorySimplyTest1 {
@Test
public void testMethod1() {
System.out.println("This is to test for method 1 for Factor Annotation");
}}
package ChromeDriver;
import org.testng.annotations.Test;
public class FactorySimpleTest2 {
@Test
public void testMethod2() {
System.out.println("This is to test for method 2 for Factor Annotation");
}
}
package ChromeDriver;
import org.testng.annotations.Factory;
import org.testng.annotations.Test;
public class FactoryAnnotation {
@Factory()
@Test
public Object[] getTestFactoryMethod() {
Object[] factoryTest = new Object[2];
factoryTest[0] = new FactorySimplyTest1();
factoryTest[1] = new FactorySimpleTest2();
return factoryTest;
}
}
控制台输出:

@参数
此注释可帮助您直接通过testNG.xml文件将参数传递给测试。 通常,当您有有限的数据集进行测试时,这是首选。 如果数据集复杂而又庞大,则@dataProvider批注为首选或优于excel。
下面的代码片段展示了相同的内容:
@Parameters({ "username", "password"})
@Test()
public void checkLogin(String username, String password)
{
driver.get("https://accounts.lambdatest.com/login");
driver.findElement(By.xpath("//input[@name='email']")).sendKeys(username);
driver.findElement(By.xpath("//input[@name='password']")).sendKeys(password);
driver.findElement(By.xpath("//*[@id='app']/section/form/div/div/button")).click();
System.out.println("The login process on lamdatest is completed");
}
参数值在TestNG.xml文件中定义,如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Suite">
<test thread-count="5" name="Annotations">
<parameter name="username" value="sadhvisingh24@gmail.com" />
<parameter name="password" value="XXXXX" />
<classes>
<class name="Parameter_annotation"/>
</classes>
</test> <!-- Annotations -->
</suite> <!-- Suite -->
@Listener
该注释有助于记录和报告。 我们有多个侦听器,例如:
- IExecutionListener
- IAnnotationTransformer
- ISuiteListener
- ITestListener
但是深入了解这些听众及其用途将是另一个博客的话题。 我即将写一封,敬请期待。
这就是全部了!
使用所有这些注释和属性时要注意的关键点是您的系统应具有Java 1.5版本或更高版本,因为所有较低版本的Java都不支持这些注释,并且您可能会收到错误消息。
以上所有上述TestNG的注释和属性有助于为代码提供更好的结构和可读性。 它有助于提供详细的报告,从而使状态报告变得更加轻松和有用。 在TestNG for Selenium中使用这些注释完全取决于您的业务需求。 因此,选择正确的使用方法很重要。现在就在LambdaTest Selenium Grid的TestNG中试用这些注释!

翻译自: https://www.javacodegeeks.com/2019/04/complete-guid-testng-annotations-selenium-webdriver.html