TestNG 教程

⚡ 智能摘要

TestNG 是下一代 Java 与以下测试框架配合使用 Selenium 用于结构化自动化、丰富的报告和并行执行。本教程涵盖核心注解和项目设置。 Eclipse编写第一个测试用例、HTML 报告和高级参数用法。

  • 🧱 核心框架: TestNG 扩展 JUnit 带有注释的想法,小组ping以及并行测试执行 Selenium 套房。
  • 🏷️ 注释驱动流程: @Test、@BeforeMethod、@AfterMethod、@BeforeTest 和 @AfterTest 顺序设置、测试和清理。
  • 🗂️ Eclipse 建立: 建立一个您自己的 TestNG 项目,添加 TestNG 图书馆和 Selenium 然后使用向导生成 JAR 包和测试类。
  • 📊 报告: TestNG 在测试输出文件夹中生成文本、图形和 HTML 报告,包括按时间顺序排列的视图。
  • ⚙️ 参数: 使用 priority、alwaysRun 和 dataProvider 来控制执行顺序并将数据提供给测试。
  • 🤖 人工智能提升: AI编码助手加速 TestNG 类生成、定位器更新和数据提供程序脚手架。

TestNG 教程

什么是 TestNG?

TestNG 是一个自动化测试框架,其中“NG”代表“下一代”。 TestNG 受启发 JUnit 和用途 Java 使用注解(@)来控制测试流程。它克服了…… JUnit早期的局限性,旨在实现 端到端测试 更容易。

与 TestNG 您可以生成一份完整的报告,并立即查看有多少测试通过、失败或被跳过。您还可以仅重新运行失败的测试用例。

例如:

  • 假设你有五个测试用例,每个用例都在各自的方法中编写,但没有进行任何修改。 TestNG前三个测试通过,第四个测试失败。修复第四个测试后,你只想重新运行这一个测试,因为前三个测试已经通过了。这用普通的 main() 方法代码很难实现。
  • TestNG 提供了一个 testng-failed.xml 文件中 test-output 文件夹。运行该 XML 文件只会重新执行失败的用例。

除此之外,你还将了解到以下方面的优势: TestNG如何使用 @Test 注解编写测试方法,以及如何将类转换为可从 [此处应填写源代码] 运行的测试套件 Eclipse 或者通过命令行。

为何使用 TestNG - Selenium?

默认情况下, Selenium 测试结果格式不佳。 TestNG 接入测试运行程序后,它会生成一个结构化报告,您可以与团队共享该报告。

桥梁 Selenium 用户偏好 TestNG 超过 JUnit 因为它具有更丰富的功能。主要功能包括: Selenium 是:

  • 报告包括已运行、已通过、已失败和已跳过的测试用例数量。
  • 简易组ping 通过测试用例 testng.xml 文件,并设置执行优先级。
  • 使用以下方法多次重复测试,无需循环: invocationCount.
  • 在多个浏览器上运行多个测试——跨浏览器浏览器测试 支持。
  • 与Maven无缝集成, Jenkins以及其他 CI 工具。
  • Readable 注解——例如,@BeforeMethod、@AfterMethod、@BeforeTest、@AfterTest。
  • Selenium WebDriver本身没有报告功能; TestNG 它用如下所示的简洁 HTML 报告填补了这一空白。

TestNG HTML 报告示例 Selenium 测试

  • TestNG 简化了测试代码。你不再需要静态的 main 方法;注解决定了哪些代码运行以及何时运行。

通常 Java 测试类结构及其主方法

TestNG 使用注解的测试类结构

  • 未捕获的异常会被优雅地处理。 TestNG这些步骤会被报告为失败步骤,但不会终止整个运行。

的优点 TestNG 超过 JUnit

TestNG 与……相比,它具有三大主要优势。 JUnit:

  • 注释更容易理解和使用。
  • 测试用例可以更轻松地进行分组和优先级排序。
  • 开箱即用,支持并行测试执行。

什么是注释? TestNG?

中的注释 TestNG 是放置在方法上方的代码行,用于控制方法的执行方式。 它们总是以@符号开头。下面是一个简单的例子。

例如: TestNG 上方注释 Java 方法

注释的详细介绍请参见该部分。 “注释中使用的 TestNG= 本教程稍后会用到,所以上面的例子只是为了让大家有个概念。 TestNG 注释比……更容易编写和阅读 JUnit 等效项,它们在运行测试时至关重要。 Selenium 格 在并行执行至关重要的场合。

如何编写测试用例 TestNG

写 TestNG 测试用例包含三个步骤:

  1. 编写业务逻辑并放置 TestNG 每个方法上方都有注释。
  2. 添加元数据,例如类名、组名和包名。
  3. 运行 TestNG 从您的 IDE 或命令行调用类。

使用以下方式创建测试用例 TestNG 注释

现在我们将使用以下方式创建我们的第一个测试用例 TestNG 注释 Selenium在编写测试之前,请设置一个新的 TestNG 项目 Eclipse 并称之为 名字TestNG项目.

设置新 TestNG 项目

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

Eclipse 创建新菜单 Java 项目

步骤2) 输入 名字TestNG项目 作为项目名称并点击 下一篇.

全新发布 Java 项目向导,名为“First”TestNG项目

步骤3) 导入 TestNG 图书馆。点击 图书馆 选项卡然后 添加图书馆….

“库”选项卡,其中包含“添加库”选项 Eclipse

步骤4)添加图书馆 对话框中,选择 TestNG 并点击 下一篇.

选择 TestNG 在“添加库”对话框中

步骤5) 点击 完成.

完成“添加库”向导

TestNG 现在应该会出现在图书馆列表中。

TestNG 在图书馆列表中可见

步骤6) 添加包含以下内容的 JAR 文件 Selenium API。这些信息来自…… Java 从客户端驱动程序下载 selenium.dev/downloads.

在“添加外部 JAR”对话框中 Eclipse

导航到该文件夹 Selenium JAR文件已存储。

选择 Selenium 构建路径的 JAR 文件

添加外部 JAR 文件后,屏幕应如下所示。

Selenium 已将 JAR 文件添加到库列表中

步骤7) 点击 完成。 新 名字TestNG项目 出现在软件包资源管理器中。

名字TestNG项目在包资源管理器中可见

如何创建一个新的 TestNG 测试文件

项目准备就绪后,创建一个新的 TestNG 文件中。

步骤1) 用鼠标右键单击 src 文件夹并选择 新品 > 其他….

从 src 文件夹创建新的“其他”菜单 Eclipse

步骤2) 展开 TestNG 文件夹,选择 TestNG 程和点击 下一篇.

TestNG 新建向导中的类选项

步骤3) 输入下方显示的值,然后点击 完成。 该 Java 文件被命名 名字TestNG文件.

TestNG 第一类巫师TestNG文件值

步骤4) Eclipse 产生 TestNG 模板如下所示。

产生 TestNG 类模板 Eclipse 编辑

编写你的第一个代码 TestNG 测试用例

创建第一个 测试用例 验证标题 Mercury 旅游主页。

package firsttestngpackage;

import org.openqa.selenium.WebDriver;
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/";
    public WebDriver driver;

    @Test
    public void verifyHomepageTitle() {
        System.out.println("launching firefox browser");
        // Selenium 4 ships Selenium Manager, so the driver path is no longer required.
        driver = new FirefoxDriver();
        driver.get(baseUrl);
        String expectedTitle = "Welcome: Mercury Tours";
        String actualTitle = driver.getTitle();
        Assert.assertEquals(actualTitle, expectedTitle);
        driver.quit();
    }
}

需要注意的事项:

  • TestNG 不需要 main() 方法。
  • 方法不必是静态的。
  • @测试 注释标记 verifyHomepageTitle() 作为测试案例。
  • 注释存在于 org.testng.annotations.* 包。
  • 断言 班级来自 org.testng.Assert 驱动验证。

您可以在单个容器中使用多个 @Test 注解。 TestNG 文件。我们将在文件中介绍这一点。 “注释中使用的 TestNG= 部分。

运行测试

右键单击该文件并以其他方式运行。 TestNG 测试。 Eclipse 产生两个输出——控制台窗口中的文本结果和图形结果。 TestNG 结果窗口。

TestNG 结果窗口显示测试结果

Eclipse 控制台窗口 TestNG 文本输出

检查由以下人员创建的报告 TestNG

控制台窗口提供基于文本的摘要,而 TestNG 结果窗口显示图形视图。

文字与图形 TestNG 结果比较

生成 HTML 报告

TestNG 还可以生成完整的HTML报告。

步骤1) 跑完之后 名字TestNG文件右键单击项目并选择 刷新.

刷新选项 TestNG 项目 Eclipse

步骤2) A 测试输出 文件夹出现。展开并找到 index.html — 最近一次运行的 HTML 报告。

测试输出文件夹,其中 index.html 文件已高亮显示

步骤3) Double单击 index.html 打开它 Eclipse浏览器。下次运行时按 F5 刷新。

TestNG HTML索引报告以以下格式呈现 Eclipse

注释中使用的 TestNG

您已经了解了 @Test 注解。本节的其余部分将介绍最有用的高级注解。

多个测试用例

一个单一的 TestNG 一个文件可以包含多个 @Test 注解。默认情况下,带有 @Test 注解的方法按字母顺序执行。在下面的代码中,方法 c_test, a_testb_test 按字母顺序运行,不考虑来源顺序。

单个 @Test 方法中多个 TestNG 程

运行代码并打开 index.html。 点击 按时间顺序排列.

按时间顺序查看多个 TestNG 方法

参数

要覆盖默认排序,请使用 priority 参数。 参数是用于修改注释行为的关键字。

  • 赋值 =.
  • 将参数放在紧跟在注解后面的括号中,如下所示。

TestNG 带有参数和值语法的注解

TestNG 按优先级从低到高依次执行 @Test 注解。优先级编号无需连续。

包含 @Test 优先级参数的完整代码

HTML 报告证实,方法按优先级升序执行。

TestNG 报告显示了按优先级升序运行的方法。

多个参数

除了 priority@Test 接受 alwaysRun 参数(真或假)。 要在单个注解中使用两个或多个参数,请用逗号分隔它们:

@Test(priority = 0, alwaysRun = true)

@Test 注解中多个参数的示例

@BeforeTest 和 @AfterTest

@测试前 此注解下的方法运行 在第一个测试用例之前 TestNG 文件.
@测试后 此注解下的方法运行 在所有测试用例之后 TestNG 文件完成.

考虑下面的代码。

package firsttestngpackage;

import org.openqa.selenium.WebDriver;
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/";
    public WebDriver driver;

    @BeforeTest
    public void launchBrowser() {
        System.out.println("launching firefox browser");
        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.quit();
    }
}

根据表格和代码,我们可以预测序列将是:

  • 第一名 launchBrowser()
  • 第二 verifyHomepageTitle()
  • 第三名 terminateBrowser()

注解块在源文件中的位置不会影响它们的执行顺序。 尝试按如下所示重新排列方法。

package firsttestngpackage;

import org.openqa.selenium.WebDriver;
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/";
    public WebDriver driver;

    @AfterTest                              // Jumbled
    public void terminateBrowser() {
        driver.quit();
    }

    @BeforeTest                             // Jumbled
    public void launchBrowser() {
        System.out.println("launching firefox browser");
        driver = new FirefoxDriver();
        driver.get(baseUrl);
    }

    @Test                                   // Jumbled
    public void verifyHomepageTitle() {
        String expectedTitle = "Welcome: Mercury Tours";
        String actualTitle = driver.getTitle();
        Assert.assertEquals(actualTitle, expectedTitle);
    }
}

运行代码并验证结果。

TestNG 尽管注释混乱,但结果仍确认了订单。

@BeforeMethod 和 @AfterMethod

@前方法 此注解下的方法运行 在每种测试方法之前.
注释: 此注解下的方法运行 每次测试方法之后.

In Mercury 假设我们要验证从主页访问的两个目标页面的标题。

来自三个链接 Mercury 旅游主页

测试流程如下:

  • 打开首页并核实其标题。
  • 单击“注册”并验证其目标页面的标题。
  • 返回首页并核对标题。
  • 单击“支持”并验证其目标页面的标题。
  • 返回首页并再次核对标题。

下面的代码展示了 @BeforeMethod 和 @AfterMethod 如何处理重复步骤。

package firsttestngpackage;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
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/";
    public WebDriver driver;
    public String expected = null;
    public String actual = null;

    @BeforeTest
    public void launchBrowser() {
        System.out.println("launching firefox browser");
        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.quit();
    }
}

测试运行完毕后, TestNG 报告如下序列。

TestNG 使用 BeforeMethod 和 AfterMethod 报告序列

简而言之:将设置步骤放在内部 @前方法 以及内部清理或导航重置 注释: 因此,每个测试用例都以已知状态开始和结束。

概要 TestNG 注释

  • @BeforeSuite: 在测试套件中的所有测试之前运行。
  • @AfterSuite: 在测试套件中的所有测试完成后运行。
  • @BeforeTest: 在属于类内部的任何测试方法之前运行标签。
  • @AfterTest: 在属于类的所有测试方法之后运行标签。
  • @BeforeGroups: 在属于任何已列出组的第一个测试方法之前不久运行。
  • @AfterGroups: 在属于任何已列出组的最后一个测试方法执行完毕后不久运行。
  • @课前: 在当前类中的第一个测试方法之前运行。
  • @AfterClass: 在当前类中的所有测试方法完成后运行。
  • @BeforeMethod: 在每个测试方法之前运行。
  • @AfterMethod: 每个测试方法运行后都会执行。
  • @测试: 将该方法标记为测试用例。

常见问题

JUnit 5个现代化 JUnit 采用 Jupiter API 和扩展模型。 TestNG 仍然领先于并行执行、套件级组ping依赖于和数据提供程序。许多 Selenium 球队选择 TestNG 适用于端到端套件和 JUnit 5. 用于单元测试。

在 `<T>` 标签中添加 `parallel="methods"` 或 `parallel="classes"` 以及线程数属性。 testng.xml 中的标签。 TestNG 然后将测试方法分布到各个线程中,这非常适合 Selenium 网格或云端跨浏览器运行。

@DataProvider 将多个数据集传递给单个 @Test 方法。提供程序中的每一行都代表一次执行。这是数据驱动测试的标准模式。 Selenium 针对表单、搜索框或登录屏幕进行测试。

是的。 AI 编码助手生成 TestNG 从示例 CSV 中创建框架、注释 @Test 方法、构建页面对象类和绘制 DataProvider 数组,从而大幅缩短脚手架搭建时间。

生成式人工智能会读取 testng-results.xml 和 Surefire 日志,对相似的故障进行聚类,提示可能的根本原因,并创建 Jira 问题单。这缩短了不稳定测试的排查时间,并帮助质量保证负责人确定持续集成修复的优先级。

总结一下这篇文章: