TestNG 教程

什么是 TestNG?

TestNG 是一个自动化测试框架,其中 NG 代表“下一代”。TestNG 的灵感来自 JUnit,它使用注解(@)。TestNG 克服了 JUnit 的缺点,旨在使端到端测试变得容易。

使用 TestNG,您可以生成一份适当的报告,并且可以轻松了解有多少测试用例通过、失败和跳过。您可以单独执行失败的测试用例。

例如

  • 假设您有五个测试用例,每个测试用例编写一个方法(假设程序是使用主方法编写的,没有使用 TestNG)。当您第一次运行此程序时,前三个方法成功执行,第四个方法失败。然后纠正第四个方法中存在的错误,现在您只想运行第四个方法,因为前三个方法无论如何都已成功执行。这在不使用 TestNG 的情况下是不可能的。
  • Selenium 中的 TestNG 提供了一个选项,即 test-output 文件夹中的 testng-failed.xml 文件。如果您只想运行失败的测试用例,这意味着您运行此 XML 文件。它将只执行失败的测试用例。

除了上述概念,您还将学习更多关于 TestNG 的知识,例如 TestNG 的优点是什么,如何使用 @test 注解创建测试方法,如何将这些类转换为测试套件文件并通过 Eclipse 以及命令行执行。

为什么将 TestNG 与 Selenium 一起使用?

默认的 Selenium 测试不会生成适当格式的测试结果。在 Selenium 中使用 TestNG,我们可以生成测试结果。

大多数 Selenium 用户更喜欢使用它而不是JUnit,因为它具有优势。TestNG 有许多功能,但我们只会关注在 Selenium 中可以使用的最重要功能。以下是 Selenium TestNG 的主要功能:

  • 生成格式正确的报告,包括运行的测试用例数量、通过的测试用例数量、失败的测试用例数量和跳过的测试用例数量。
  • 通过将多个测试用例转换为 testng.xml 文件,可以更轻松地对它们进行分组。在其中,您可以设置哪个测试用例应该首先执行的优先级。
  • 无需循环,只需使用关键字“invocation count”即可多次执行相同的测试用例。
  • 使用 testng,您可以在多个浏览器上执行多个测试用例,即跨浏览器测试
  • TestNG 框架可以轻松与 TestNG Maven、Jenkins 等工具集成。
  • 测试中使用的注解非常容易理解,例如:@BeforeMethod、@AfterMethod、@BeforeTest、@AfterTest
  • WebDriver 没有原生机制来生成报告。TestNG 可以生成可读格式的报告,如下所示。
  • Use TestNG with Selenium

  • TestNG 简化了测试的编码方式。我们的测试中不再需要静态 main 方法。动作序列由易于理解的注解控制,这些注解不需要方法是静态的。
  • Use TestNG with Selenium

    Use TestNG with Selenium

  • TestNG 会自动处理未捕获的异常,而不会过早终止测试。这些异常会在报告中报告为失败的步骤。

TestNG 相对于 JUnit 的优势

TestNG 相对于 JUnit 有三个主要优势:

  • 注解更容易理解
  • 测试用例可以更轻松地分组
  • 并行测试是可能的

TestNG 中的注解是什么?

TestNG 中的注解是代码行,可以控制其下方方法的执行方式。它们总是以 @ 符号开头。一个非常早期且快速的 TestNG 示例如下所示。

Annotation in TestNG

注解将在名为“TestNG 中使用的注解”一节中讨论,因此如果您现在还不理解上面的 TestNG 示例,那也完全没关系。目前重要的是要注意,TestNG 中的注解比 JUnit 更容易编码和理解。

TestNG 中提供了并行运行测试的功能,而 JUnit 中没有,因此使用 Selenium Grid 的测试人员更倾向于 TestNG 框架。

如何在 TestNG 中编写测试用例?

步骤 1) 编写您的业务逻辑并在代码中插入 TestNG 注解。
步骤 2) 添加更多信息,如类名、组名、包名等
步骤 3) 运行 TestNG。

使用 TestNG 注解创建测试用例

现在,我们将学习如何在 Selenium 中使用 TestNG 注解创建我们的第一个测试用例

在创建测试用例之前,我们应该首先在 Eclipse 中设置一个新的 TestNG 项目,并将其命名为“FirstTestNGProject”。

设置新的 TestNG 项目

步骤 1:点击文件 > 新建 > Java 项目

Setting up a new TestNG Project

步骤 2:输入“FirstTestNGProject”作为项目名称,然后单击“下一步”。

Setting up a new TestNG Project

步骤 3:现在我们将开始将 TestNG 库导入到我们的项目中。点击“库”选项卡,然后点击“添加库…”

Setting up a new TestNG Project

步骤 4:在“添加库”对话框中,选择“TestNG”,然后单击“下一步”。

Setting up a new TestNG Project

步骤 5:点击“完成”。

Setting up a new TestNG Project

您应该注意到 TestNG 已包含在库列表中。

Setting up a new TestNG Project

步骤 6:现在我们将添加包含 Selenium API 的 JAR 文件。这些文件在我们之前章节安装 Selenium 和 Eclipse 时从 https://selenium.net.cn/downloads/ 下载的 Java 客户端驱动程序中找到。

Setting up a new TestNG Project

然后,导航到您放置 Selenium JAR 文件的位置。

Setting up a new TestNG Project

添加外部 JAR 后,您的屏幕应如下所示。

Setting up a new TestNG Project

步骤 7:单击“完成”并验证我们的 FirstTestNGProject 在 Eclipse 的包资源管理器窗口中是否可见。

Setting up a new TestNG Project

如何创建新的 TestNG 测试文件

现在我们已经完成了本 TestNG 教程中的项目设置,让我们创建一个新的 TestNG 文件。

步骤 1:点击“src”并选择“其他”。
右键单击“src”包文件夹,然后选择“新建”>“其他…”

Create a New TestNG Test File

步骤 2:选择 TestNG 类。
点击 TestNG 文件夹,选择“TestNG 类”选项。点击“下一步”。

Create a New TestNG Test File

步骤 3:输入数值。
在相应的输入框中输入以下指示的值,然后单击“完成”。请注意,我们将 Java 文件命名为“FirstTestNGFile”。

Create a New TestNG Test File

步骤 4:模板已创建。
Eclipse 应自动为我们的 TestNG 文件创建如下所示的模板。

Create a New TestNG Test File

我们的第一个 TestNG 测试用例示例的编码

现在让我们创建第一个测试用例,它将检查 Mercury Tours 的主页是否正确。输入您的代码,如以下 TestNG 示例所示:

package firsttestngpackage;
import org.openqa.selenium.*;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.testng.Assert;
import org.testng.annotations.*;

public class firsttestngfile {
    public String baseUrl = "https://demo.guru99.com/test/newtours/";
    String driverPath = "C:\\geckodriver.exe";
    public WebDriver driver ; 
     
  @Test
  public void verifyHomepageTitle() {
       
      System.out.println("launching firefox browser"); 
      System.setProperty("webdriver.gecko.driver", driverPath);
      driver = new FirefoxDriver();
      driver.get(baseUrl);
      String expectedTitle = "Welcome: Mercury Tours";
      String actualTitle = driver.getTitle();
      Assert.assertEquals(actualTitle, expectedTitle);
      driver.close();
  }
}

请注意以下几点。

  • TestNG 不需要您拥有 main() 方法。
  • 方法不需要是静态的。
  • 我们使用了 @Test 注解。@Test 用于表明其下方的方法是一个测试用例。在这种情况下,我们将 verifyHomepageTitle() 方法设置为我们的测试用例,因此我们在其上方放置了一个“@Test”注解。
  • 由于我们在 TestNG 中使用注解,因此需要导入 org.testng.annotations.* 包。
  • 我们使用了 Assert 类。Assert 类用于在 TestNG 中执行验证操作。要使用它,我们需要导入 org.testng.Assert 包。

您可以在一个 TestNG 文件中拥有多个测试用例(因此有多个 @Test 注解)。这将在后面“TestNG 中使用的注解”一节中更详细地讨论。

运行测试

要运行测试,只需像平时一样在 Eclipse 中运行文件即可。Eclipse 将提供两个输出——一个在控制台窗口中,另一个在 TestNG 结果窗口中。

Running the Test

Running the Test

检查 TestNG 创建的报告

Eclipse 中的控制台窗口提供我们测试用例结果的文本报告,而 TestNG 结果窗口提供图形报告。

Checking Reports Created by TestNG

生成 HTML 报告

TestNG 能够生成 HTML 格式的报告。

步骤 1:在运行我们在上一节中创建的 FirstTestNGFile 后,右键单击项目资源管理器窗口中的项目名称 (FirstTestNGProject),然后单击“刷新”选项。

Generating HTML Reports

步骤 2:请注意,已创建了一个“test-output”文件夹。展开它并查找 index.html 文件。此 HTML 文件是最近一次测试运行结果的报告。

Generating HTML Reports

步骤 3:双击该 index.html 文件以在 Eclipse 内置的 Web 浏览器中打开它。您可以在重新运行测试后随时刷新此页面,就像在普通 Web 浏览器中一样,只需按 F5 即可。

Generating HTML Reports

TestNG 中使用的注解

在上一节中,您已经了解了 @Test 注解。现在,我们将学习更高级的注解及其用法。

多个测试用例

我们可以在一个 TestNG 文件中使用多个 @Test 注解。默认情况下,由 @Test 注解的方法按字母顺序执行。请参阅以下代码。尽管方法 c_test、a_test 和 b_test 在代码中并未按字母顺序排列,但它们将按此顺序执行。

Annotations used in TestNG

运行此代码并在生成的 index.html 页面上,点击“时间顺序视图”。

Annotations used in TestNG

参数

如果您希望方法以不同的顺序执行,请使用参数“priority”。参数是修改注解功能的关键字

  • 参数需要您为其分配一个值。您可以通过在其后放置“=”符号,然后跟上值来实现。
  • 参数包含在一对括号中,这些括号放在注解之后,如下图所示的代码片段。

Parameters

TestNG 将从最低优先级值到最高优先级值执行 @Test 注解。您的优先级值不需要连续。

Parameters

TestNG HTML 报告将确认方法是根据优先级升序执行的。

Parameters

多个参数

除了“priority”之外,@Test 还有另一个参数名为“alwaysRun”,它只能设置为“true”或“false”。要在单个注解中使用两个或更多参数,请用逗号将它们分开,如下所示。

@Test(priority = 0, alwaysRun = true)

Multiple Parameters

@BeforeTest 和 @AfterTest

@BeforeTest 此注解下的方法将在 TestNG 文件中的第一个测试用例之前执行。
@AfterTest 此注解下的方法将在 TestNG 文件中的所有测试用例执行之后执行。

考虑下面的代码。

package firsttestngpackage;
import org.openqa.selenium.*;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.testng.Assert;
import org.testng.annotations.*;
public class firsttestngfile {
    public String baseUrl = "https://demo.guru99.com/test/newtours/";
    String driverPath = "C:\\geckodriver.exe";
    public WebDriver driver ; 
     
     @BeforeTest
      public void launchBrowser() {
          System.out.println("launching firefox browser"); 
          System.setProperty("webdriver.gecko.driver", driverPath);
          driver = new FirefoxDriver();
          driver.get(baseUrl);
      }
      @Test
      public void verifyHomepageTitle() {
          String expectedTitle = "Welcome: Mercury Tours";
          String actualTitle = driver.getTitle();
          Assert.assertEquals(actualTitle, expectedTitle);
     }
      @AfterTest
      public void terminateBrowser(){
          driver.close();
      }
}

应用表格和上述代码呈现的逻辑,我们可以预测方法的执行顺序为:

  • 1st – launchBrowser()
  • 2nd – verifyHomepageTitle()
  • 3rd – terminateBrowser()

注解块的位置可以互换,而不影响它们的执行时间顺序。让我们通过一个 TestNG 示例来理解,并尝试重新排列注解块,使您的代码看起来类似于下面的代码。

package firsttestngpackage;
import org.openqa.selenium.*;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.testng.Assert;
import org.testng.annotations.*;
public class firsttestngfile {
    public String baseUrl = "https://demo.guru99.com/test/newtours/";
    String driverPath = "C:\\geckodriver.exe";
    public WebDriver driver ; 
     @AfterTest                            //Jumbled
      public void terminateBrowser(){
          driver.close();
      }
     @BeforeTest                            //Jumbled
      public void launchBrowser() {
          System.out.println("launching firefox browser"); 
          System.setProperty("webdriver.gecko.driver", driverPath);
          driver = new FirefoxDriver();
          driver.get(baseUrl);
      }
      @Test                                //Jumbled
      public void verifyHomepageTitle() {
          String expectedTitle = "Welcome: Mercury Tours";
          String actualTitle = driver.getTitle();
          Assert.assertEquals(actualTitle, expectedTitle);
     }
      
}

运行上面的代码并注意

Multiple Parameters

@BeforeMethod 和 @AfterMethod

@BeforeMethod 此注解下的方法将在每个测试用例中的每个方法之前执行。
@AfterMethod 此注解下的方法将在每个测试用例中的每个方法之后执行。

在 Mercury Tours 中,假设我们想验证以下两个链接的目标页面的标题。

Multiple Parameters

我们的测试流程将是

  • 访问主页并验证其标题。
  • 点击“注册”并验证其目标页面的标题。
  • 返回主页并验证其标题是否仍然正确。
  • 点击“支持”并验证其目标页面的标题。
  • 返回主页并验证其标题是否仍然正确。

下面的代码演示了如何使用 @BeforeMethod 和 @AfterMethod 高效地执行上述场景。

package firsttestngpackage;
import org.openqa.selenium.*;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.testng.Assert;
import org.testng.annotations.*;
@Test
public class firsttestngfile {
    public String baseUrl = "https://demo.guru99.com/test/newtours/";
    String driverPath = "C:\\geckodriver.exe";
    public WebDriver driver; 
    public String expected = null;
    public String actual = null;
        @BeforeTest
      public void launchBrowser() {
          System.out.println("launching firefox browser"); 
          System.setProperty("webdriver.gecko.driver", driverPath);
          driver= new FirefoxDriver();
          driver.get(baseUrl);
      }
      
      @BeforeMethod
      public void verifyHomepageTitle() {
          String expectedTitle = "Welcome: Mercury Tours";
          String actualTitle = driver.getTitle();
          Assert.assertEquals(actualTitle, expectedTitle);
      }
          @Test(priority = 0)
      public void register(){
          driver.findElement(By.linkText("REGISTER")).click() ;
          expected = "Register: Mercury Tours";
          actual = driver.getTitle();
          Assert.assertEquals(actual, expected);
      }
          @Test(priority = 1)
      public void support() {
            driver.findElement(By.linkText("SUPPORT")).click() ;
            expected = "Under Construction: Mercury Tours";
            actual = driver.getTitle();
            Assert.assertEquals(actual, expected);
      }
      @AfterMethod
      public void goBackToHomepage ( ) {
            driver.findElement(By.linkText("Home")).click() ;
      }
       
      @AfterTest
      public void terminateBrowser(){
          driver.close();
      }
}

执行此测试后,您的 TestNG 应报告以下序列。

Multiple Parameters

简而言之,@BeforeMethod 应包含您需要在每个测试用例之前运行的方法,而 @AfterMethod 应包含您需要在每个测试用例之后运行的方法。

TestNG 注解摘要

@BeforeSuite:带注解的方法将在本套件中的所有测试运行之前运行。

@AfterSuite:带注解的方法将在本套件中的所有测试运行之后运行。

@BeforeTest:带注解的方法将在标签内类的任何测试方法运行之前运行。

@AfterTest:带注解的方法将在标签内类的所有测试方法运行之后运行。

@BeforeGroups:此配置方法将在其运行之前运行的组列表。此方法保证在属于这些组的第一个测试方法被调用之前不久运行。

@AfterGroups:此配置方法将在其运行之后运行的组列表。此方法保证在属于这些组的最后一个测试方法被调用之后不久运行。

@BeforeClass:带注解的方法将在当前类中的第一个测试方法被调用之前运行。

@AfterClass:带注解的方法将在当前类中的所有测试方法运行之后运行。

@BeforeMethod:带注解的方法将在每个测试方法之前运行。

@AfterMethod:带注解的方法将在每个测试方法之后运行。

@Test:带注解的方法是测试用例的一部分

结论

  • TestNG 是一个测试框架,能够使 Selenium 测试更容易理解,并生成易于理解的报告。
  • TestNG 相对于 JUnit 的主要优点如下。
    • 注解更容易使用和理解。
    • 测试用例可以更容易地分组。
    • TestNG 允许我们创建并行测试
  • Eclipse 中的控制台窗口生成基于文本的结果,而 TestNG 窗口更有用,因为它为我们提供了测试结果的图形输出以及其他有意义的详细信息,例如:
    • 每个方法的运行时长。
    • 方法执行的时间顺序
  • TestNG 能够生成基于 HTML 的报告。
  • 注解可以使用参数,就像普通的 Java TestNG 方法一样。
  • TestNG Dataprovider 是一种将参数传递给测试函数的方式,该函数在单次执行中将不同的值传递给测试用例。