和平,劳动,五月,哈布罗夫斯克居民! 对于像我们这样的人,每个周末都需要休假,我们准备了一份翻译,希望与
Java QA工程师课程的报名开始同步,该课程计划于5月28日启动。
TestNG是CédricBeust创建的测试框架 ,可以帮助我们满足许多测试需求。 TestNG被广泛用于硒。 想知道NG的意思吗? 这意味着
“下一代” 。 TestNG与JUnit相似,但是在控制程序流方面更强大。 框架的体系结构可帮助我们使测试更加结构化并提供更好的验证点。
TestNG的一些功能值得关注:
- 强大而多样的注释来支持您的测试案例。
- 使用测试之间的依赖关系并行运行测试。
- 通过TestNG.xml文件或通过数据提供程序的概念,可以在不同的数据集上运行测试的灵活性。
- 测试用例的分组和优先级。
- 生成HTML报告,使用各种插件进行自定义。
- 生成测试执行日志。
- 易于与Eclipse,Maven,Jenkins等集成。
通常,使用TestNG的测试过程包括以下步骤:

在继续使用Selenium的TestNG批注之前,我们概述了设置TestNG的先决条件。
先决条件:
- Java开发套件
- Eclipse或任何其他IDE
- 在Eclipse或IDE中安装了TestNG
注意:Java批注只能与Java 1.5版或更高版本一起使用。
如果您不
熟悉TestNG ,请参阅有关如何
使用TestNG运行第
一个自动化脚本的文章。
那么什么是注释?注释是提供有关类或方法的附加信息的标签( 译者注:java中的注释不仅可以应用于类和方法,还可以应用于其他元素 )。 对于注释,使用前缀“ @”。 TestNG使用注释来帮助创建强大的测试框架。 让我们看一下用Selenium自动执行测试的TestNG批注。
@Test
这是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( currentUrl, "https://automation.lambdatest.com/timeline/?viewType=build&page=1", "url did not matched"); }
@BeforeTest
在使用@Test
注释运行第一个方法之前,将运行具有此注释的方法。 (译者注:作为xml配置文件的test
部分中定义的test
一部分) 。 您可以在带有Selenium的TestNG中使用此批注来配置浏览器。 例如,启动浏览器并将其扩展到全屏,设置特定的浏览器设置等。
以下是BeforeTest的示例,其中浏览器扩展到全屏:
@BeforeTest public void profileSetup() { driver.manage().window().maximize(); }
@AfterTest
标有此批注的方法在测试的所有@Test
方法之后运行。 (
译者注:作为xml配置文件中test
部分中定义的test
一部分,“当前类”未正确地用原始语言编写 )。 这是一个有用的注释,可用于提供测试结果。 您可以使用此批注创建有关测试的报告,并将其通过电子邮件发送给感兴趣的各方。
代码示例:
@AfterTest public void reportReady() { System.out.println("Report is ready to be shared, with screenshots of tests"); }
@BeforeMethod
具有此批注的方法在每个@Test
方法之前运行 。 在运行测试之前,可以使用它来测试与数据库的连接。 或者,例如,当测试取决于用户登录名的功能时,请在此处输入代码以进入系统。
以下是演示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("activa9049"); driver.findElement(By.xpath("//*[@id='app']/section/form/div/div/button")).click(); }
@AfterMethod
具有注解的方法在每个@Test
方法之后启动 。 您可以在每次运行测试时使用此批注来截取屏幕截图。
以下是演示如何截屏的代码片段:
@AfterMethod public void screenShot() throws IOException { TakesScreenshot scr = ((TakesScreenshot) driver); File file1 = scr.getScreenshotAs(OutputType.FILE); FileUtils.copyFile(file1, new File(":\\test-output\\test1.PNG")); }
@BeforeClass
具有此批注的方法将在当前类中的第一个测试方法之前执行。 您可以使用此批注来配置浏览器属性,初始化驱动程序,使用所需的URL打开浏览器等。
BeforeClass的示例代码:
@BeforeClass public void appSetup() { driver.get(url); }
@AfterClass
具有此注释的方法将在当前类中的最后一个测试方法之后执行。 TestNG中的此批注可用于在测试完成后执行清理资源的操作,例如关闭驱动程序等。
以下是显示驱动程序关闭的代码段示例:
@AfterClass public void closeUp() { driver.close(); }
@BeforeSuite
一个测试套件(套件)可以由几个类组成,此批注在所有类的所有测试方法之前运行。
此批注标记启动时的入口点。 TestNG中的
@BeforeSuite
可用于执行常见功能,例如设置和运行Selenium或远程Web驱动程序等。
TestNG中的示例
@BeforeSuite
批注显示驱动程序设置:
@BeforeSuite public void setUp() { System.setProperty( "webdriver.chrome.driver", ":\\selenium\\chromedriver.exe"); driver = new ChromeDriver(); }
@AfterSuite
在所有类中的所有测试方法都已运行之后,TestNG中的此批注开始。 当您使用多个类(例如,关闭驱动程序等)时,可以使用此注释在完成测试之前进行清理。
下面是TestNG for Selenium中
@AfterSuite
批注的代码片段:
@AfterSuite public void cleanUp() { System.out.println("All close up activities completed"); }
@BeforeGroups
TestNG可以使用
@Test
批注中的group属性将测试分组在一起。 例如,如果您希望将与用户管理相关的所有类似功能组合在一起,则可以将测试(例如仪表板(用户面板),配置文件(配置文件),交易(交易)等)标记为一组,例如user_management。 TestNG中的
@BeforeGroups
有助于在指定的测试组之前启动某些操作。 如果小组专注于一种功能,则可以使用此注释,如上面的示例所示。
@BeforeGroup
可能包含一个登录功能,该功能是在组中运行测试所必需的,例如,测试用户面板,用户配置文件等。
使用
@BeforeGroups
的示例:
@BeforeGroups("urlValidation") public void setUpSecurity() { System.out.println("url validation test starting"); }
@AfterGroups
在执行指定组的所有测试方法后,将启动此批注。Selenium的TestNG中
@AfterGroups
批注的示例代码:
@AfterGroups("urlValidation") public void tearDownSecurity() { System.out.println("url validation test finished"); }
例子下面的代码显示了使用上面讨论的所有注释的示例:
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.*; import java.io.File; import java.io.IOException; import java.util.concurrent.TimeUnit; import static org.testng.Assert.assertEquals; public class AnnotationsTestNG { private WebDriver driver; private String url = "https://www.lambdatest.com/"; @BeforeSuite public void setUp() { System.setProperty( "webdriver.chrome.driver", ":\\selenium\\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(":\\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报告:
控制台输出:
译者注:
- 要运行测试,请在setUp()方法中将路径更改为chromedriver.exe,并在screenShot()方法中将路径更改为屏幕快照文件夹。 另外,为了成功执行测试,checkLogin()方法必须具有有效的用户名和密码。
- 使用的Maven依赖项:
<dependencies> <dependency> <groupId>org.testng</groupId> <artifactId>testng</artifactId> <version>6.14.3</version> <scope>test</scope> </dependency> <dependency> <groupId>org.seleniumhq.selenium</groupId> <artifactId>selenium-chrome-driver</artifactId> <version>3.141.59</version> <scope>test</scope> </dependency> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.6</version> <scope>test</scope> </dependency> </dependencies>
硒的TestNG批注序列上述注释在运行时按以下顺序执行:
- 套房
- 测试前
- 上课前
- 团体前
- 前方法
- 测验
- 后方法
- 后组
- 课后
- 后测
- 后套房
这是它们的执行顺序:
与TestNG中的注释一起使用的属性TestNG中的注释具有可用于自定义的属性。 它们有助于设置测试方法的执行顺序。
这些属性是:
- description :您可以指定测试方法的描述。
例如,@ Test(描述=“此测试检查登录名”)。 - alwaysRun :此属性确保即使删除了测试方法依赖的测试,也将始终执行该测试方法。 当属性值为true时,此方法将始终运行。
例如,@ @Test
(alwaysRun = true)。 - dataProvider :设置测试方法的数据提供者的名称。 假设您要在多个浏览器中运行测试,然后在带有dataProvider属性的test方法中,可以为浏览器及其版本添加参数,这些参数将由数据提供者传递给该方法。 在这种情况下,包含此属性的测试将使用此输入在多个浏览器中运行测试。
例如,@ @Test
(dataProvider =“跨浏览器测试”)。 - dependsOnMethods :提供有关运行测试顺序的信息。 仅当此属性依赖的测试成功时,才会执行该属性的测试。 如果该方法所依赖的测试失败,则该测试不会开始。
例如,@ Test(depenOnmethod =“ login”)。 - 组 :有助于将针对一种功能的测试方法归为一组。
例如,@ @Test
(组=“ Payment_Module”)。
此属性还允许您控制要运行的测试。 运行测试时,您可以忽略某些组,或者相反,仅运行某些组。 您需要做的就是在TestNG.xml文件中指定必要的组。 在include
标记中,指定需要运行的组,在exclude
标记中,应将其忽略。 - dependsOnGroups :执行上述两个属性的功能,即确定测试方法对指定组的依赖性。 仅在完成指定的测试组之后,才会启动此测试方法。
例如,@ Test(depenOnMethods =“ Payment_Module”)。 - 优先级 :帮助我们确定测试方法的优先级。 当TestNG运行测试方法时,它可以随机执行。 在希望测试以正确顺序运行的情况下,可以使用优先级属性。 所有测试方法的默认优先级均为0。首先,以较低的优先级值运行测试。
例如,@ @Test
(优先级= 1),@ @Test
(优先级= 2)。 在这种情况下,将首先执行优先级等于1的测试,然后执行优先级2的测试。 - enabled :需要忽略而不运行特定测试时使用此属性。 您所要做的就是将其设置为false。
例如,@ @Test
(enabled = false)。 - timeout :定义应该完成测试的时间。 如果测试执行超过属性指定的时间,则测试将失败,并引发org.testng.internal.thread.ThreadTimeoutException异常
例如,@ @Test
(timeOut = 500)。 请注意,时间以毫秒为单位 。 - invocationCount :就像循环一样工作。 该测试将运行invocationCount中指定的次数。
例如,@ @Test
(invocationCount = 5)将运行5次。 - invocationTimeOut :与上述invocationCount属性一起使用。 该属性的值与invocationCount一起指示测试将在invocationCount中指定的时间内以及在invocationTimeOut属性中指定的时间内运行多次。
例如,@ @Test
(invocationCount = 5,invocationTimeOut = 20)。 - ExpectedExceptions :帮助处理预期在测试方法中引发的异常。 如果测试方法引发了属性中指定的异常,则测试成功。 否则,缺少一个异常或抛出该属性中未指定的另一个异常将使测试失败。
例如,@ @Test
(expectedExceptions = {ArithmeticException.class})。
上面是带有Selenium的TestNG中与批注一起使用的属性。 以下是演示上述属性的用法的代码段:
import static org.testng.Assert.assertEquals; import java.io.File; import java.io.IOException; 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.BeforeSuite; import org.testng.annotations.BeforeTest; import org.testng.annotations.Test; public class AnnotationsTest { private WebDriver driver; private String url = "https://www.lambdatest.com/"; @BeforeSuite public void setUp() { System.setProperty( "webdriver.chrome.driver", ":\\selenium\\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( currentUrl, "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(":\\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属性的测试方法。 此方法有助于创建数据驱动的测试,可以将多组输入值传递到这些测试中。 该方法应返回二维数组或对象。
@DataProvider
批注具有两个属性:
- 名称 -此属性用于指示数据提供者的名称。 如果未指定,则使用默认方法名称。
- 并行 -此属性使您可以与其他数据并行运行测试。 拥有此属性是TestNG与Junit相比的优势之一。 默认值为false。
下面的示例显示了
@DataProvider
批注与给定名称和并行属性的结合使用。
@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
此批注有助于通过一个测试类运行多个测试类。 简而言之,它动态定义和创建测试。
下面的代码片段显示了
@Factory
批注的用法,该批注有助于调用测试类方法。
import org.testng.annotations.Test; import org.testng.annotations.Factory; class FactorySimplyTest1 { @Test public void testMethod1() { System.out.println("This is to test for method 1 for Factor Annotation"); } } class FactorySimpleTest2 { @Test public void testMethod2() { System.out.println("This is to test for method 2 for Factor Annotation"); } } public class FactoryAnnotation { @Factory() @Test public Object[] getTestFactoryMethod() { Object[] factoryTest = new Object[2]; factoryTest[0] = new FactorySimplyTest1(); factoryTest[1] = new FactorySimpleTest2(); return factoryTest; } }
控制台输出:
@Parameters
此批注允许您通过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中尝试这些注释!
读完那些内容的人都将被邀请参加免费的
在线研讨会 ,该
研讨会将于5月14日由我们的老师
Dmitry Eremin举办 。 好吧,按照既定传统,我们正在等待您的评论,朋友。