- 测试NG教程
- 测试NG - 主页
- TestNG - 概述
- TestNG - 环境
- TestNG - 编写测试
- TestNG - 基本注释
- TestNG - 执行过程
- TestNG - 执行测试
- TestNG - 套件测试
- TestNG - 忽略测试
- TestNG - 小组测试
- TestNG - 异常测试
- TestNG - 依赖性测试
- TestNG - 参数化测试
- TestNG - 运行 JUnit 测试
- TestNG - 测试结果
- TestNG - 注释变压器
- TestNG - 断言
- TestNG - 并行执行
- TestNG - 带 ANT 的插头
- TestNG - 使用 Eclipse 进行插件
- TestNG - TestNG - 与 JUnit
- TestNG 有用资源
- TestNG - 快速指南
- TestNG - 有用的资源
- TestNG - 讨论
TestNG - 快速指南
TestNG - 概述
测试是检查应用程序功能以确保其按要求工作的过程。单元测试出现在开发人员级别,其中采取适当的措施来测试每个实体(类或方法),以确保最终产品满足要求。
与任何其他测试框架相比,JUnit 促使开发人员了解测试(尤其是单元测试)的有用性。JUnit凭借着相当简单、务实、严谨的架构,已经“感染”了一大批开发者。请查看我们的 JUnit 教程,以更好地了解其功能。同时,JUnit 也有一些缺点,如下所示 -
最初设计仅用于单元测试,现在用于各种测试。
无法进行依赖性测试。
配置控制(setUp/tearDown)较差。
侵入性(迫使您扩展类并以某种方式命名您的方法)。
静态编程模型(强制您不必要地重新编译)。
复杂项目中不同测试套件的管理可能非常棘手。
什么是 TestNG?
TestNG 根据其文档的定义如下 -
TestNG 是一个受 JUnit 和 NUnit 启发的测试框架,但引入了一些新功能,使其更强大且更易于使用。
TestNG是一个开源的自动化测试框架;其中NG表示下一代G。 _ _ TestNG 类似于 JUnit(尤其是 JUnit 4),但它不是 JUnit 扩展。它的灵感来自于 JUnit。它被设计为比 JUnit 更好,特别是在测试集成类时。TestNG 的创建者是Cedric Beust。
TestNG 消除了旧框架的大部分限制,使开发人员能够编写更灵活、更强大的测试。由于它大量借用 Java Annotations(随 JDK 5.0 引入)来定义测试,因此它还可以向您展示如何在实际生产环境中使用 Java 语言的这一新功能。
测试NG特点
支持注释。
TestNG 使用更多 Java 和 OO 功能。
支持测试集成类(例如,默认情况下,无需为每个测试方法创建新的测试类实例)。
将编译时测试代码与运行时配置/数据信息分开。
灵活的运行时配置。
引入“测试组”。编译测试后,您可以要求 TestNG 运行所有“前端”测试,或“快”、“慢”、“数据库”测试等。
支持相关测试方法、并行测试、负载测试和部分失败。
灵活的插件API。
支持多线程测试。
TestNG - 环境
TestNG 是一个 Java 框架,因此第一个要求是在您的计算机上安装 JDK。
系统要求
JDK | 1.5或以上。 |
记忆 | 没有最低要求。 |
磁盘空间 | 没有最低要求。 |
操作系统 | 没有最低要求。 |
第 1 步 - 验证计算机中的 Java 安装
打开控制台并根据您系统上安装的操作系统执行 java 命令。
操作系统 | 任务 | 命令 |
---|---|---|
Windows | 打开命令控制台 | c:\> java -版本 |
Linux | 打开命令终端 | $ java -版本 |
苹果 | 打开终端 | 机器:~ Joseph$ java -版本 |
让我们验证所有操作系统的输出 -
操作系统 | 输出 |
---|---|
Windows | java版本“1.7.0_25” Java(TM) SE 运行时环境(版本 1.7.0_25-b15) Java HotSpot(TM) 64 位服务器 VM(内部版本 23.25-b01,混合模式) |
Linux | java版本“1.7.0_25” Java(TM) SE 运行时环境(版本 1.7.0_25-b15) Java HotSpot(TM) 64 位服务器 VM(内部版本 23.25-b01,混合模式) |
苹果 | java版本“1.7.0_25” Java(TM) SE 运行时环境(版本 1.7.0_25-b15) Java HotSpot(TM) 64 位服务器 VM(内部版本 23.25-b01,混合模式) |
如果您没有 Java,请从https://www.oracle.com/technetwork/java/javase/downloads/index.html安装 Java 软件开发工具包 (SDK) 。我们假设 Java 1.7.0_25 作为本教程的安装版本。
第二步:设置JAVA环境
将JAVA_HOME环境变量设置为指向计算机上安装 Java 的基本目录位置。例如,
操作系统 | 输出 |
---|---|
Windows | 将环境变量 JAVA_HOME 设置为 C:\Program Files\Java\jdk1.7.0_25。 |
Linux | 导出 JAVA_HOME=/usr/local/java-current。 |
苹果 | 导出 JAVA_HOME=/Library/Java/Home。 |
将 Java 编译器位置附加到系统路径。
操作系统 | 输出 |
---|---|
Windows | 将字符串 C:\Program Files\Java\jdk1.7.0_25\bin 添加到系统变量 Path 的末尾。 |
Linux | 导出 PATH=$PATH:$JAVA_HOME/bin/ |
苹果 | 不需要 |
如上所述,使用命令java -version验证 Java 安装。
第 3 步:下载 TestNG 存档
从http://www.testng.org下载最新版本的 TestNG jar 文件。在编写本教程时,我们已经下载了testng-6.8.jar并将其复制到 C:\> TestNG 文件夹中。
操作系统 | 档案名称 |
---|---|
Windows | testng-6.8.jar |
Linux | testng-6.8.jar |
苹果 | testng-6.8.jar |
步骤4:设置TestNG环境
将TESTNG_HOME环境变量设置为指向基本目录位置,其中 TestNG jar 存储在您的计算机上。下表显示了如何在 Windows、Linux 和 Mac 中设置环境变量,假设我们已将 testng-6.8.jar 存储在位置 C:\>TestNG。
操作系统 | 描述 |
---|---|
Windows | 将环境变量 TESTNG_HOME 设置为 C:\TESTNG。 |
Linux | 导出 TESTNG_HOME=/usr/local/TESTNG |
苹果 | 导出 TESTNG_HOME=/Library/TESTNG |
第 5 步:设置 CLASSPATH 变量
设置CLASSPATH环境变量以指向 TestNG jar 位置。
操作系统 | 描述 |
---|---|
Windows | 将环境变量 CLASSPATH 设置为 %CLASSPATH%;%TESTNG_HOME%\testng-6.8.jar。 |
Linux | 导出 CLASSPATH=$CLASSPATH:$TESTNG_HOME/testng-6.8.jar。 |
苹果 | 导出 CLASSPATH=$CLASSPATH:$TESTNG_HOME/testng-6.8.jar。 |
第 6 步:测试 TestNG 设置
在C:\>TestNG_WORKSPACE中创建名为 TestNGSimpleTest 的 java 类文件。
import org.testng.annotations.Test; import static org.testng.Assert.assertEquals; public class TestNGSimpleTest { @Test public void testAdd() { String str = "TestNG is working fine"; AssertEquals("TestNG is working fine", str); } }
TestNG 可以通过几种不同的方式调用 -
- 使用 testng.xml 文件。
- 与蚂蚁。
- 从命令行。
让我们使用 testng.xml 文件进行调用。在C:\>TestNG_WORKSPACE中创建名为 testng.xml 的 xml 文件来执行测试用例。
<?xml version = "1.0" encoding = "UTF-8"?> <!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" > <suite name = "Suite1"> <test name = "test1"> <classes> <class name = "TestNGSimpleTest"/> </classes> </test> </suite>
第 7 步:验证结果
使用javac编译器编译该类,如下所示 -
C:\TestNG_WORKSPACE>javac TestNGSimpleTest.java
现在,调用 testng.xml 来查看结果 -
C:\TestNG_WORKSPACE>java -cp "C:\TestNG_WORKSPACE" org.testng.TestNG testng.xml
验证输出。
=============================================== Suite1 Total tests run: 1, Failures: 0, Skips: 0 ===============================================
TestNG - 编写测试
在 TestNG 中编写测试基本上涉及以下步骤 -
编写测试的业务逻辑并在代码中插入 TestNG 注释。
在 testng.xml 文件或 build.xml 中添加有关测试的信息(例如类名称、您希望运行的组等)。
运行测试NG。
在这里,我们将看到一个使用 POJO 类、业务逻辑类和测试 xml 进行 TestNG 测试的完整示例,该示例将由 TestNG 运行。
在C:\>TestNG_WORKSPACE中创建EmployeeDetails.java,这是一个 POJO 类。
public class EmployeeDetails { private String name; private double monthlySalary; private int age; // @return the name public String getName() { return name; } // @param name the name to set public void setName(String name) { this.name = name; } // @return the monthlySalary public double getMonthlySalary() { return monthlySalary; } // @param monthlySalary the monthlySalary to set public void setMonthlySalary(double monthlySalary) { this.monthlySalary = monthlySalary; } // @return the age public int getAge() { return age; } // @param age the age to set public void setAge(int age) { this.age = age; } }
EmployeeDetails类用于 -
- 获取/设置员工姓名的值。
- 获取/设置员工的月薪值。
- 获取/设置员工年龄的值。
在C:\>TestNG_WORKSPACE中创建EmpBusinessLogic.java,其中包含业务逻辑。
public class EmpBusinessLogic { // Calculate the yearly salary of employee public double calculateYearlySalary(EmployeeDetails employeeDetails) { double yearlySalary = 0; yearlySalary = employeeDetails.getMonthlySalary() * 12; return yearlySalary; } // Calculate the appraisal amount of employee public double calculateAppraisal(EmployeeDetails employeeDetails) { double appraisal = 0; if(employeeDetails.getMonthlySalary() < 10000) { appraisal = 500; } else { appraisal = 1000; } return appraisal; } }
EmpBusinessLogic类用于计算 -
- 雇员的年薪。
- 员工的考核金额。
现在,让我们在 C:\>TestNG_WORKSPACE 中创建一个名为TestEmployeeDetails.java的 TestNG 类。TestNG 类是一个至少包含一个 TestNG 注释的 Java 类。该类包含要测试的测试用例。TestNG 测试可以通过 @BeforeXXX 和 @AfterXXX 注释进行配置(我们将在TestNG - 执行过程一章中看到这一点),它允许在某个点之前和之后执行一些 Java 逻辑。
import org.testng.Assert; import org.testng.annotations.Test; public class TestEmployeeDetails { EmpBusinessLogic empBusinessLogic = new EmpBusinessLogic(); EmployeeDetails employee = new EmployeeDetails(); @Test public void testCalculateAppriasal() { employee.setName("Rajeev"); employee.setAge(25); employee.setMonthlySalary(8000); double appraisal = empBusinessLogic.calculateAppraisal(employee); Assert.assertEquals(500, appraisal, 0.0, "500"); } // Test to check yearly salary @Test public void testCalculateYearlySalary() { employee.setName("Rajeev"); employee.setAge(25); employee.setMonthlySalary(8000); double salary = empBusinessLogic.calculateYearlySalary(employee); Assert.assertEquals(96000, salary, 0.0, "8000"); } }
TestEmployeeDetails类用于测试EmpBusinessLogic 类的方法。它执行以下操作 -
测试员工的年薪。
测试员工的考核金额。
在运行测试之前,必须使用特殊的 XML 文件(通常命名为 testng.xml)配置 TestNG。该文件的语法非常简单,其内容如下所示。在C:\>TestNG_WORKSPACE中创建此文件。
<?xml version = "1.0" encoding = "UTF-8"?> <!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" > <suite name = "Suite1"> <test name = "test1"> <classes> <class name = "TestEmployeeDetails"/> </classes> </test> </suite>
上述文件的详细信息如下 -
一套由一个 XML 文件表示。它可以包含一个或多个测试,并由 <suite> 标记定义。
标签 <test> 代表一个测试,可以包含一个或多个 TestNG 类。
<class> 标签代表一个 TestNG 类。它是一个至少包含一个 TestNG 注释的 Java 类。它可以包含一种或多种测试方法。
使用 javac 编译测试用例类。
C:\TestNG_WORKSPACE>javac EmployeeDetails.java EmpBusinessLogic.java TestEmployeeDetails.java
现在使用以下命令测试NG -
C:\TestNG_WORKSPACE>java -cp "C:\TestNG_WORKSPACE" org.testng.TestNG testng.xml
如果一切都正确完成,您应该在控制台中看到测试结果。此外,TestNG 在一个名为test-output 的文件夹中创建了一个非常漂亮的 HTML 报告,该文件夹是在当前目录中自动创建的。如果您打开它并加载index.html,您将看到一个类似于下图所示的页面 -
TestNG - 基本注释
在 JUnit 3 中指示测试方法的传统方法是在其名称前加上 test 前缀。这是一种非常有效的方法,可以将类中的某些方法标记为具有特殊含义,但是命名的扩展性不太好(如果我们想为不同的框架添加更多标记怎么办?)并且相当不灵活(如果我们想为不同的框架添加更多标记怎么办?)想要将附加参数传递给测试框架吗?)。
注解在 JDK 5 中正式添加到 Java 语言中,TestNG 选择使用注解来注解测试类。
以下是 TestNG 支持的注释列表 -
先生。 | 注释和描述 |
---|---|
1 | @BeforeSuite 在该套件中的所有测试运行之前,带注释的方法将仅运行一次。 |
2 | @AfterSuite 带注释的方法将仅在该套件中的所有测试运行后运行一次。 |
3 | @课前 在调用当前类中的第一个测试方法之前,带注释的方法将仅运行一次。 |
4 | @下课以后 被注解的方法只会在当前类中的所有测试方法运行完毕后运行一次。 |
5 | @测试前 带注释的方法将在运行属于 <test> 标记内的类的任何测试方法之前运行。 |
6 | @测试后 带注释的方法将在属于 <test> 标记内的类的所有测试方法运行后运行。 |
7 | @BeforeGroups 此配置方法之前将运行的组的列表。该方法保证在调用属于任何这些组的第一个测试方法之前不久运行。 |
8 | @AfterGroups 此配置方法将在其后运行的组列表。该方法保证在调用属于任何这些组的最后一个测试方法后不久运行。 |
9 | @方法之前 带注释的方法将在每个测试方法之前运行。 |
10 | @AfterMethod 带注释的方法将在每个测试方法之后运行。 |
11 | @DataProvider 将方法标记为为测试方法提供数据。被注释的方法必须返回一个Object[][],其中每个Object[]可以被分配测试方法的参数列表。想要从此 DataProvider 接收数据的 @Test 方法需要使用与该批注名称相同的 dataProvider 名称。 |
12 | @工厂
将方法标记为工厂,该工厂返回将由 TestNG 作为测试类使用的对象。该方法必须返回 Object[ ]。 |
13 | @听众 定义测试类的侦听器。 |
14 | @参数 描述如何将参数传递给@Test方法。 |
15 | @测试 将类或方法标记为测试的一部分。 |
使用注释的好处
以下是使用注释的一些好处 -
TestNG 通过查找注释来识别它感兴趣的方法。因此,方法名称不限于任何模式或格式。
我们可以将附加参数传递给注释。
注释是强类型的,因此编译器会立即标记任何错误。
测试类不再需要扩展任何东西(例如 JUnit 3 的 TestCase)。
TestNG - 执行过程
本章解释了TestNG中方法的执行过程。它解释了调用方法的顺序。以下是 TestNG 测试 API 方法的执行过程和示例。
在C:\>TestNG_WORKSPACE中创建一个名为TestngAnnotation.java的java类文件来测试注释。
import org.testng.annotations.Test; import org.testng.annotations.BeforeMethod; import org.testng.annotations.AfterMethod; import org.testng.annotations.BeforeClass; import org.testng.annotations.AfterClass; import org.testng.annotations.BeforeTest; import org.testng.annotations.AfterTest; import org.testng.annotations.BeforeSuite; import org.testng.annotations.AfterSuite; public class TestngAnnotation { // test case 1 @Test public void testCase1() { System.out.println("in test case 1"); } // test case 2 @Test public void testCase2() { System.out.println("in test case 2"); } @BeforeMethod public void beforeMethod() { System.out.println("in beforeMethod"); } @AfterMethod public void afterMethod() { System.out.println("in afterMethod"); } @BeforeClass public void beforeClass() { System.out.println("in beforeClass"); } @AfterClass public void afterClass() { System.out.println("in afterClass"); } @BeforeTest public void beforeTest() { System.out.println("in beforeTest"); } @AfterTest public void afterTest() { System.out.println("in afterTest"); } @BeforeSuite public void beforeSuite() { System.out.println("in beforeSuite"); } @AfterSuite public void afterSuite() { System.out.println("in afterSuite"); } }
接下来,我们在C:\>TestNG_WORKSPACE中创建文件testng.xml来执行注释。
<?xml version = "1.0" encoding = "UTF-8"?> <!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" > <suite name = "Suite1"> <test name = "test1"> <classes> <class name = "TestngAnnotation"/> </classes> </test> </suite>
使用 javac 编译测试用例类。
C:\TestNG_WORKSPACE>javac TestngAnnotation.java
现在,运行 testng.xml,它将运行提供的测试用例类中定义的测试用例。
C:\TestNG_WORKSPACE>java org.testng.TestNG testng.xml
验证输出。
in beforeSuite in beforeTest in beforeClass in beforeMethod in test case 1 in afterMethod in beforeMethod in test case 2 in afterMethod in afterClass in afterTest in afterSuite =============================================== Suite Total tests run: 2, Failures: 0, Skips: 0 ===============================================
根据以上输出,执行过程如下 -
首先,beforeSuite()方法只执行一次。
最后,afterSuite() 方法仅执行一次。
即使是 beforeTest()、beforeClass()、afterClass() 和 afterTest() 方法也只执行一次。
beforeMethod() 方法在每个测试用例执行之前执行。
afterMethod() 方法针对每个测试用例执行,但在执行测试用例之后执行。
在 beforeMethod() 和 afterMethod() 之间,每个测试用例都会执行。
TestNG - 执行测试
测试用例使用TestNG类执行。此类是在 TestNG 框架中运行测试的主要入口点。用户可以创建自己的 TestNG 对象并以多种不同的方式调用它,例如 -
在现有的 testng.xml 上。
在完全由 Java 创建的合成 testng.xml 上。
通过直接设置测试类。
您还可以定义要包含或排除哪些组、分配参数等。命令行参数是 -
-d outputdir:指定输出目录。
-testclass class_name:指定一个或多个类名。
-testjar jar_name:指定包含测试的 jar。
-sourcedir src1;src2: ; 分隔的源目录列表(仅在使用 javadoc 注释时使用)。
-目标
-组
-测试运行工厂
-监听者
在下面的示例中,我们将在现有的 testng.xml 中创建 TestNG 对象。
创建一个类
创建一个要测试的 java 类,例如C:\>TestNG_WORKSPACE中的MessageUtil.java。
/* * This class prints the given message on console. */ public class MessageUtil { private String message; //Constructor //@param message to be printed public MessageUtil(String message) { this.message = message; } // prints the message public String printMessage() { System.out.println(message); return message; } }
创建测试用例类
创建一个 java 测试类,例如SampleTest.java。
将测试方法 testPrintMessage() 添加到您的测试类中。
将注释@Test 添加到方法testPrintMessage()。
使用 TestNG 的assertEquals API 实现测试条件并检查条件。
在C:\>TestNG_WORKSPACE中创建一个名为SampleTest.java的 java 类文件。
import org.testng.Assert; import org.testng.annotations.Test; public class SampleTest { String message = "Hello World"; MessageUtil messageUtil = new MessageUtil(message); @Test public void testPrintMessage() { Assert.assertEquals(message, messageUtil.printMessage()); } }
创建testng.xml
接下来,让我们在C:\>TestNG_WORKSPACE中创建 testng.xml 文件,以执行测试用例。该文件以 XML 形式捕获整个测试。该文件可以轻松地在一个文件中描述所有测试套件及其参数,您可以在代码存储库中检查该文件或通过电子邮件发送给同事。它还可以轻松提取测试的子集或拆分多个运行时配置(例如,testngdatabase.xml 将仅运行运行数据库的测试)。
<?xml version = "1.0" encoding = "UTF-8"?> <suite name = "Sample test Suite"> <test name = "Sample test"> <classes> <class name = "SampleTest" /> </classes> </test> </suite>
使用 javac 编译测试用例。
C:\TestNG_WORKSPACE>javac MessageUtil.java SampleTest.java
现在,运行 testng.xml,它将运行 <test> 标记中定义的测试用例。
C:\TestNG_WORKSPACE>java -cp "C:\TestNG_WORKSPACE" org.testng.TestNG testng.xml
验证输出。
Hello World =============================================== Sample test Suite Total tests run: 1, Failures: 0, Skips: 0 ===============================================
TestNG - 套件测试
测试套件是旨在测试软件程序的一个Behave或一组Behave的测试用例的集合。在TestNG中,我们不能在测试源代码中定义一个套件,而是用一个XML文件来表示,因为套件是执行的特征。它还允许灵活配置要运行的测试。套件可以包含一个或多个测试,并由 <suite> 标签定义。
<suite> 是 testng.xml 的根标签。它描述了一个测试套件,该套件又由多个 <test> 部分组成。
下表列出了 <suite> 接受的所有合法属性。
先生。 | 属性及描述 |
---|---|
1 | 姓名 这间套房的名称。它是一个强制属性。 |
2 | 冗长的 此次运行的级别或详细程度。 |
3 | 平行线 TestNG 是否应该运行不同的线程来运行该套件。 |
4 | 线程数 如果启用并行模式,则要使用的线程数(否则忽略)。 |
5 | 注释 您在测试中使用的注释类型。 |
6 | 暂停 将用于此测试中找到的所有测试方法的默认超时。 |
在本章中,我们将向您展示一个示例,其中包含两个测试类 Test1 和 Test2,它们可以使用测试套件一起运行。
创建一个类
创建一个要测试的 java 类,例如C:\>JUNIT_WORKSPACE中的MessageUtil.java。
/* * This class prints the given message on console. */ public class MessageUtil { private String message; // Constructor // @param message to be printed public MessageUtil(String message) { this.message = message; } // prints the message public String printMessage() { System.out.println(message); return message; } // add "Hi!" to the message public String salutationMessage() { message = "Hi!" + message; System.out.println(message); return message; } }
创建测试用例类
在C:\>TestNG_WORKSPACE中创建一个名为Test1.java的 java 类文件。
import org.testng.Assert; import org.testng.annotations.Test; public class Test1 { String message = "Manisha"; MessageUtil messageUtil = new MessageUtil(message); @Test public void testPrintMessage() { System.out.println("Inside testPrintMessage()"); Assert.assertEquals(message, messageUtil.printMessage()); } }
在C:\>TestNG_WORKSPACE中创建一个名为Test2.java的 java 类文件。
import org.testng.Assert; import org.testng.annotations.Test; public class Test2 { String message = "Manisha"; MessageUtil messageUtil = new MessageUtil(message); @Test public void testSalutationMessage() { System.out.println("Inside testSalutationMessage()"); message = "Hi!" + "Manisha"; Assert.assertEquals(message,messageUtil.salutationMessage()); } }
现在,让我们在C:\>TestNG_WORKSPACE中编写 testng.xml ,其中包含 <suite> 标签,如下所示 -
<?xml version = "1.0" encoding = "UTF-8"?> <!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" > <suite name = "Suite1"> <test name = "exampletest1"> <classes> <class name = "Test1" /> </classes> </test> <test name = "exampletest2"> <classes> <class name = "Test2" /> </classes> </test> </suite>
Suite1 包括exampletest1和exampletest2。
使用 javac 编译所有 java 类。
C:\TestNG_WORKSPACE>javac MessageUtil.java Test1.java Test2.java
现在,运行 testng.xml,它将运行提供的测试用例类中定义的测试用例。
C:\TestNG_WORKSPACE>java -cp "C:\TestNG_WORKSPACE" org.testng.TestNG testng.xml
验证输出。
Inside testPrintMessage() Manisha Inside testSalutationMessage() Hi!Manisha =============================================== Suite1 Total tests run: 2, Failures: 0, Skips: 0 ===============================================
您还可以检查测试输出文件夹。在Suite1文件夹下,您可以看到创建的两个 html 文件,exampletest1.html 和 exampletest2.html,如下所示 -
TestNG - 忽略测试
有时,我们的代码还没有准备好,并且为测试该方法/代码而编写的测试用例失败了。在这种情况下,注释@Test(enabled = false)有助于禁用此测试用例。
如果测试方法使用@Test(enabled = false)注解,则将绕过未准备好测试的测试用例。
现在,让我们看看 @Test(enabled = false) 的实际效果。
创建一个类
创建一个要测试的 java 类,例如C:\>TestNG_WORKSPACE中的MessageUtil.java。
/* * This class prints the given message on console. */ public class MessageUtil { private String message; //Constructor //@param message to be printed public MessageUtil(String message) { this.message = message; } // prints the message public String printMessage() { System.out.println(message); return message; } // add "Hi!" to the message public String salutationMessage() { message = "Hi!" + message; System.out.println(message); return message; } }
创建测试用例类
创建一个 java 测试类,例如IgnoreTest.java。
将测试方法 testPrintMessage() 和 testSalutationMessage() 添加到您的测试类中。
将注释 @Test(enabled = false) 添加到方法 testPrintMessage() 中。
在C:\>TestNG_WORKSPACE中创建一个名为IgnoreTest.java的 java 类文件。
import org.testng.Assert; import org.testng.annotations.Test; public class IgnoreTest { String message = "Manisha"; MessageUtil messageUtil = new MessageUtil(message); @Test(enabled = false) public void testPrintMessage() { System.out.println("Inside testPrintMessage()"); message = "Manisha"; Assert.assertEquals(message, messageUtil.printMessage()); } @Test public void testSalutationMessage() { System.out.println("Inside testSalutationMessage()"); message = "Hi!" + "Manisha"; Assert.assertEquals(message, messageUtil.salutationMessage()); } }
创建testng.xml
在C:\>TestNG_WORKSPACE中创建 testng.xml以执行测试用例。
<?xml version = "1.0" encoding = "UTF-8"?> <!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" > <suite name = "Suite1"> <test name = "test1"> <classes> <class name = "IgnoreTest" /> </classes> </test> </suite>
使用 javac 编译 MessageUtil 和测试用例类。
C:\TestNG_WORKSPACE>javac MessageUtil.java IgnoreTest.java
现在,运行 testng.xml,它不会运行在提供的测试用例类中定义的测试用例 testPrintMessage()。
C:\TestNG_WORKSPACE>java -cp "C:\TestNG_WORKSPACE" org.testng.TestNG testng.xml
验证输出。testPrintMessage() 测试用例未经过测试。
Inside testSalutationMessage() Hi!Manisha =============================================== Suite1 Total tests run: 1, Failures: 0, Skips: 0 ===============================================
您还可以忽略一组测试,这将在下一章中讨论。
TestNG - 小组测试
组测试是TestNG中的一个新的创新功能,这是JUnit框架中不存在的。它允许您将方法分派到适当的部分并执行复杂的测试方法分组。
您不仅可以声明属于组的方法,还可以指定包含其他组的组。然后,可以调用 TestNG 并要求包含一组特定的组(或正则表达式),同时排除另一组。
组测试在如何划分测试方面提供了最大的灵活性,并且如果您想连续运行两组不同的测试,则不需要重新编译任何内容。
组是使用 <groups> 标记在 testng.xml 文件中指定的。它可以在 <test> 或 <suite> 标签下找到。<suite> 标记中指定的组适用于下面的所有 <test> 标记。
现在,我们通过一个例子来看看小组测试是如何进行的。
创建一个类
创建一个要测试的 java 类,例如C:\> TestNG_WORKSPACE中的MessageUtil.java。
/* * This class prints the given message on console. */ public class MessageUtil { private String message; // Constructor // @param message to be printed public MessageUtil(String message) { this.message = message; } // prints the message public String printMessage() { System.out.println(message); return message; } // add "tutorialspoint" to the message public String salutationMessage() { message = "tutorialspoint" + message; System.out.println(message); return message; } // add "www." to the message public String exitMessage() { message = "www." + message; System.out.println(message); return message; } }
创建测试用例类
创建一个 java 测试类,例如 GroupTestExample.java。
将测试方法 testPrintMessage() 和 testSalutationMessage() 添加到您的测试类中。
将测试方法分为两类 -
签入测试 (checkintest) - 这些测试应在提交新代码之前运行。它们通常应该很快,并且确保基本功能不会被破坏。
功能测试(functest) - 这些测试应该涵盖软件的所有功能,并且每天至少运行一次,尽管理想情况下您希望连续运行它们。
在C:\>TestNG_WORKSPACE中创建名为GroupTestExample.java的 java 类文件。
import org.testng.Assert; import org.testng.annotations.Test; public class GroupTestExample { String message = ".com"; MessageUtil messageUtil = new MessageUtil(message); @Test(groups = { "functest", "checkintest" }) public void testPrintMessage() { System.out.println("Inside testPrintMessage()"); message = ".com"; Assert.assertEquals(message, messageUtil.printMessage()); } @Test(groups = { "checkintest" }) public void testSalutationMessage() { System.out.println("Inside testSalutationMessage()"); message = "tutorialspoint" + ".com"; Assert.assertEquals(message, messageUtil.salutationMessage()); } @Test(groups = { "functest" }) public void testingExitMessage() { System.out.println("Inside testExitMessage()"); message = "www." + "tutorialspoint"+".com"; Assert.assertEquals(message, messageUtil.exitMessage()); } }
创建testng.xml
在C:\> TestNG_WORKSPACE中创建 testng.xml ,以执行测试用例。在这里,我们将仅执行属于functest组的那些测试。
<?xml version = "1.0" encoding = "UTF-8"?> <!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" > <suite name = "Suite1"> <test name = "test1"> <groups> <run> <include name = "functest" /> </run> </groups> <classes> <class name = "GroupTestExample" /> </classes> </test> </suite>
使用 javac 编译 MessageUtil、测试用例类。
C:\TestNG_WORKSPACE>javac MessageUtil.java GroupTestExample.java
现在,运行 testng.xml,它将仅运行方法 testPrintMessage(),因为它属于functest组。
C:\TestNG_WORKSPACE>java -cp "C:\TestNG_WORKSPACE" org.testng.TestNG testng.xml
验证输出。仅执行方法 testPrintMessage()。
Inside testPrintMessage() .com Inside testExitMessage() www..com =============================================== Suite1 Total tests run: 2, Failures: 1, Skips: 0 ===============================================
团体团体
组还可以包括其他组。这些组称为元组。例如,您可能想要定义一个包含checkintest和functest的组。让我们修改 testng.xml 文件如下 -
<?xml version = "1.0" encoding = "UTF-8"?> <!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" > <suite name = "Suite1"> <test name = "test1"> <groups> <define name = "all"> <include name = "functest"/> <include name = "checkintest"/> </define> <run> <include name = "all"/> </run> </groups> <classes> <class name = "GroupTestExample" /> </classes> </test> </suite>
执行上面的 testng.xml 将执行所有三个测试,并给出以下结果 -
Inside testPrintMessage() .com Inside testSalutationMessage() tutorialspoint.com Inside testExitMessage() www.tutorialspoint.com =============================================== Suite1 Total tests run: 3, Failures: 0, Skips: 0 ===============================================
排除群体
您可以使用 <exclude> 标签忽略组,如下所示 -
<?xml version = "1.0" encoding = "UTF-8"?> <!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" > <suite name = "Suite1"> <test name = "test1"> <groups> <define name = "all"> <exclude name = "functest"/> <include name = "checkintest"/> </define> <run> <include name = "all"/> </run> </groups> <classes> <class name = "GroupTestExample" /> </classes> </test> </suite>
TestNG - 异常测试
TestNG 提供了跟踪代码异常处理的选项。您可以测试代码是否引发所需的异常。这里,expectedExceptions参数与 @Test 注释一起使用。现在,让我们看看@Test(expectedExceptions) 的实际效果。
创建一个类
创建一个要测试的 java 类,例如C:\> TestNG_WORKSPACE中的MessageUtil.java。在 printMessage() 方法中添加错误条件。
/* * This class prints the given message on console. */ public class MessageUtil { private String message; //Constructor //@param message to be printed public MessageUtil(String message) { this.message = message; } // prints the message public void printMessage() { System.out.println(message); int a =0; int b = 1/a; } // add "Hi!" to the message public String salutationMessage() { message = "Hi!" + message; System.out.println(message); return message; } }
创建测试用例类
创建一个 java 测试类,例如ExpectedExceptionTest.java。
将预期异常 ArithmeticException 添加到 testPrintMessage() 测试用例。
在C:\> TestNG_WORKSPACE中创建一个名为ExpectedExceptionTest.java的 java 类文件。
import org.testng.Assert; import org.testng.annotations.Test; public class ExpectedExceptionTest { String message = "Manisha"; MessageUtil messageUtil = new MessageUtil(message); @Test(expectedExceptions = ArithmeticException.class) public void testPrintMessage() { System.out.println("Inside testPrintMessage()"); messageUtil.printMessage(); } @Test public void testSalutationMessage() { System.out.println("Inside testSalutationMessage()"); message = "Hi!" + "Manisha"; Assert.assertEquals(message,messageUtil.salutationMessage()); } }
创建测试运行程序
在C:\>TestNG_WORKSPACE中创建 testng.xml以执行测试用例。
<?xml version = "1.0" encoding = "UTF-8"?> <!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" > <suite name = "Suite1"> <test name = "test1"> <classes> <class name = "ExpectedExceptionTest" /> </classes> </test> </suite>
使用 javac 编译 MessageUtil、测试用例类。
C:\TestNG_WORKSPACE>javac MessageUtil.java TestJunit.java
现在,运行测试运行程序,它将运行提供的测试用例类中定义的测试用例。
C:\TestNG_WORKSPACE>java -cp "C:\TestNG_WORKSPACE" org.testng.TestNG testng.xml
验证输出。testPrintMessage() 测试用例将通过。
Inside testPrintMessage() Manisha Inside testSalutationMessage() Hi!Manisha =============================================== Suite1 Total tests run: 2, Failures: 0, Skips: 0 ===============================================
TestNG - 依赖性测试
有时,您可能需要按特定顺序调用测试用例中的方法,或者您可能希望在方法之间共享一些数据和状态。TestNG 支持这种依赖关系,因为它支持测试方法之间显式依赖关系的声明。
TestNG 允许您使用以下命令指定依赖项:
在@Test注释中使用属性dependsOnMethods,或者。
在@Test注释中使用属性dependsOnGroups 。
使用dependsOnMethods 的示例
创建一个类
创建一个要测试的 java 类,例如C:\>TestNG_WORKSPACE中的MessageUtil.java。
public class MessageUtil { private String message; // Constructor // @param message to be printed public MessageUtil(String message) { this.message = message; } // prints the message public String printMessage() { System.out.println(message); return message; } // add "Hi!" to the message public String salutationMessage() { message = "Hi!" + message; System.out.println(message); return message; } }
创建测试用例类
创建一个 java 测试类,例如 DependencyTestUsingAnnotation.java。
将测试方法 testPrintMessage() 和 testSalutationMessage() 以及 initEnvironmentTest() 添加到您的测试类中。
将属性dependsOnMethods = {"initEnvironmentTest"}添加到testSalutationMessage()方法的@Test注释中。
在C:\>TestNG_WORKSPACE中创建一个 java 类文件名称DependencyTestUsingAnnotation.java。
import org.testng.Assert; import org.testng.annotations.Test; public class DependencyTestUsingAnnotation { String message = "Manisha"; MessageUtil messageUtil = new MessageUtil(message); @Test public void testPrintMessage() { System.out.println("Inside testPrintMessage()"); message = "Manisha"; Assert.assertEquals(message, messageUtil.printMessage()); } @Test(dependsOnMethods = { "initEnvironmentTest" }) public void testSalutationMessage() { System.out.println("Inside testSalutationMessage()"); message = "Hi!" + "Manisha"; Assert.assertEquals(message, messageUtil.salutationMessage()); } @Test public void initEnvironmentTest() { System.out.println("This is initEnvironmentTest"); } }
创建testng.xml
在C:\>TestNG_WORKSPACE中创建 testng.xml以执行测试用例。
<?xml version = "1.0" encoding = "UTF-8"?> <!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" > <suite name = "Suite1"> <test name = "test1"> <classes> <class name = "DependencyTestUsingAnnotation" /> </classes> </test> </suite>
使用 javac 编译 MessageUtil、测试用例类。
C:\TestNG_WORKSPACE>javac MessageUtil.java DependencyTestUsingAnnotation.java
现在,运行testng.xml,它仅在执行initEnvironmentTest()方法后才运行testSalutationMessage()方法。
C:\TestNG_WORKSPACE>java -cp "C:\TestNG_WORKSPACE" org.testng.TestNG testng.xml
验证输出。
This is initEnvironmentTest Inside testPrintMessage() Manisha Inside testSalutationMessage() Hi!Manisha =============================================== Suite1 Total tests run: 3, Failures: 0, Skips: 0 ===============================================
使用dependsOnGroups 的示例
您还可以拥有依赖于整个组的方法。让我们举一个例子来证明这一点。
创建一个类
创建一个要测试的 java 类,例如C:\>TestNG_WORKSPACE中的MessageUtil.java。
public class MessageUtil { private String message; // Constructor // @param message to be printed public MessageUtil(String message) { this.message = message; } // prints the message public String printMessage() { System.out.println(message); return message; } // add "Hi!" to the message public String salutationMessage() { message = "Hi!" + message; System.out.println(message); return message; } }
创建测试用例类
创建一个 java 测试类,例如 DependencyTestUsingAnnotation.java。
将测试方法 testPrintMessage() testSalutationMessage() 和 initEnvironmentTest() 添加到测试类中,并将它们添加到“init”组中。
将属性dependsOnMethods = {"init.*"}添加到testSalutationMessage()方法的@Test注释中。
在C:\>TestNG_WORKSPACE中创建一个名为DependencyTestUsingAnnotation.java的 java 类文件。
import org.testng.Assert; import org.testng.annotations.Test; public class DependencyTestUsingAnnotation { String message = "Manisha"; MessageUtil messageUtil = new MessageUtil(message); @Test(groups = { "init" }) public void testPrintMessage() { System.out.println("Inside testPrintMessage()"); message = "Manisha"; Assert.assertEquals(message, messageUtil.printMessage()); } @Test(dependsOnGroups = { "init.*" }) public void testSalutationMessage() { System.out.println("Inside testSalutationMessage()"); message = "Hi!" + "Manisha"; Assert.assertEquals(message, messageUtil.salutationMessage()); } @Test(groups = { "init" }) public void initEnvironmentTest() { System.out.println("This is initEnvironmentTest"); } }
在此示例中,testSalutationMessage() 被声明为依赖于任何组,匹配正则表达式“init.*”,这保证了方法 testPrintMessage() 和 initEnvironmentTest() 将始终在 testSalutationMessage() 之前调用。
如果依赖的方法失败,并且您对其具有硬依赖关系(alwaysRun=false,这是默认值),则依赖于它的方法不会被标记为 FAIL,而是标记为 SKIP。跳过的方法将在最终报告中进行报告(在 HTML 中既不是红色也不是绿色的颜色),这一点很重要,因为跳过的方法不一定是失败。
创建testng.xml
在C:\>TestNG_WORKSPACE中创建 testng.xml以执行测试用例。
<?xml version = "1.0" encoding = "UTF-8"?> <!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" > <suite name = "Suite1"> <test name = "test1"> <classes> <class name = "DependencyTestUsingAnnotation" /> </classes> </test> </suite>
使用 javac 编译 MessageUtil、测试用例类。
C:\TestNG_WORKSPACE>javac MessageUtil.java DependencyTestUsingAnnotation.java
现在,运行testng.xml,它仅在执行initEnvironmentTest()方法后才运行testSalutationMessage ()方法。
C:\TestNG_WORKSPACE>java -cp "C:\TestNG_WORKSPACE" org.testng.TestNG testng.xml
验证输出。
This is initEnvironmentTest Inside testPrintMessage() Manisha Inside testSalutationMessage() Hi!Manisha =============================================== Suite1 Total tests run: 3, Failures: 0, Skips: 0 ===============================================
dependsOnGroups与dependentOnMethods
在使用组时,我们不再面临重构问题。只要我们不修改 dependentOnGroups 或 groups 属性,我们的测试就会继续运行并设置正确的依赖项。
每当需要在依赖图中添加新方法时,我们所需要做的就是将其放入正确的组中,并确保它依赖于正确的组。我们不需要修改任何其他方法。
TestNG - 参数化测试
TestNG 中另一个有趣的功能是参数测试。在大多数情况下,您会遇到业务逻辑需要大量不同数量的测试的场景。参数化测试允许开发人员使用不同的值一遍又一遍地运行相同的测试。
TestNG 允许您以两种不同的方式将参数直接传递到测试方法 -
- 使用 testng.xml
- 与数据提供商
使用testng.xml传递参数
使用此技术,您可以在testng.xml文件中定义简单参数,然后在源文件中引用这些参数。让我们通过一个例子来演示如何使用这种技术来传递参数。
创建测试用例类
创建一个 java 测试类,例如 ParameterizedTest1.java。
将测试方法parameterTest() 添加到您的测试类中。该方法接受一个字符串作为输入参数。
将注释@Parameters("myName")添加到此方法。该参数将从 testng.xml 传递一个值,我们将在下一步中看到该值。
在C:\>TestNG_WORKSPACE中创建一个名为ParameterizedTest1.java的 java 类文件。
import org.testng.annotations.Parameters; import org.testng.annotations.Test; public class ParameterizedTest1 { @Test @Parameters("myName") public void parameterTest(String myName) { System.out.println("Parameterized value is : " + myName); } }
创建testng.xml
在C:\>TestNG_WORKSPACE中创建 testng.xml以执行测试用例。
<?xml version = "1.0" encoding = "UTF-8"?> <!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" > <suite name = "Suite1"> <test name = "test1"> <parameter name = "myName" value="manisha"/> <classes> <class name = "ParameterizedTest1" /> </classes> </test> </suite>
我们还可以在 <suite> 级别定义参数。假设我们在 <suite> 和 <test> 级别都定义了myName 。在这种情况下,适用常规范围规则。这意味着 <test> 标记内的任何类都将看到 <test> 中定义的参数值,而 testng.xml 文件其余部分中的类将看到 <suite> 中定义的值。
使用 javac 编译测试用例类。
C:\TestNG_WORKSPACE>javac ParameterizedTest1.java
现在,运行 testng.xml,它将运行parameterTest方法。TestNG 将首先尝试在 <test> 标记中查找名为myName的参数,然后,如果找不到它,则会在包含该参数的 <suit> 标记中搜索。
C:\TestNG_WORKSPACE>java -cp "C:\TestNG_WORKSPACE" org.testng.TestNG testng.xml
验证输出。
Parameterized value is : manisha =============================================== Suite1 Total tests run: 1, Failures: 0, Skips: 0 ===============================================
TestNG 将自动尝试将 testng.xml 中指定的值转换为参数的类型。以下是支持的类型 -
- 细绳
- 整数/整数
- 布尔值/布尔值
- 字节/字节
- 字符/字符
- 双/双
- 浮动/浮动
- 长/长
- 短/短
与数据提供者传递参数
当需要传递复杂参数或需要从Java创建的参数(复杂对象、从属性文件或数据库读取的对象等)时,可以使用Dataproviders来传递参数。
数据提供者是用@DataProvider注释的方法。该注释只有一个字符串属性:它的名称。如果未提供名称,数据提供者的名称将自动默认为方法的名称。数据提供者返回一个对象数组。
以下示例演示了如何使用数据提供程序。第一个示例是关于 @DataProvider 使用 Vector、String 或 Integer 作为参数,第二个示例是关于 @DataProvider 使用对象作为参数。
实施例1
这里,@DataProvider 传递 Integer 和 Boolean 作为参数。
创建Java类
创建一个名为 PrimeNumberChecker.java 的 java 类。此类检查该数字是否为素数。在C:\>TestNG_WORKSPACE中创建此类。
public class PrimeNumberChecker { public Boolean validate(final Integer primeNumber) { for (int i = 2; i < (primeNumber / 2); i++) { if (primeNumber % i == 0) { return false; } } return true; } }
创建测试用例类
创建一个 java 测试类,例如 ParamTestWithDataProvider1.java。
定义方法 primeNumbers(),使用注释将其定义为数据提供者。该方法返回一个对象数组。
将测试方法 testPrimeNumberChecker() 添加到您的测试类中。该方法采用整数和布尔值作为输入参数。此方法验证传递的参数是否是素数。
在此方法中添加注释@Test(dataProvider = "test1") 。属性 dataProvider 映射到“test1”。
在C:\>TestNG_WORKSPACE中创建名为ParamTestWithDataProvider1.java的 java 类文件。
import org.testng.Assert; import org.testng.annotations.BeforeMethod; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; public class ParamTestWithDataProvider1 { private PrimeNumberChecker primeNumberChecker; @BeforeMethod public void initialize() { primeNumberChecker = new PrimeNumberChecker(); } @DataProvider(name = "test1") public static Object[][] primeNumbers() { return new Object[][] {{2, true}, {6, false}, {19, true}, {22, false}, {23, true}}; } // This test will run 4 times since we have 5 parameters defined @Test(dataProvider = "test1") public void testPrimeNumberChecker(Integer inputNumber, Boolean expectedResult) { System.out.println(inputNumber + " " + expectedResult); Assert.assertEquals(expectedResult, primeNumberChecker.validate(inputNumber)); } }
创建testng.xml
创建 testng.xml C:\>TestNG_WORKSPACE来执行测试用例。
<?xml version = "1.0" encoding = "UTF-8"?> <!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" > <suite name = "Suite1"> <test name = "test1"> <classes> <class name = "ParamTestWithDataProvider1" /> </classes> </test> </suite>
使用 javac 编译测试用例类。
C:\TestNG_WORKSPACE>.javac ParamTestWithDataProvider1.java PrimeNumberChecker.java
现在,运行 testng.xml。
C:\TestNG_WORKSPACE>java -cp "C:\TestNG_WORKSPACE" org.testng.TestNG testng.xml
验证输出。
2 true 6 false 19 true 22 false 23 true =============================================== Suite1 Total tests run: 5, Failures: 0, Skips: 0 ===============================================
实施例2
在这里,@DataProvider 将对象作为参数传递。
创建Java类
在C:\>TestNG_WORKSPACE中创建一个 java 类 Bean.java,它是一个具有 get/set 方法的简单对象。
public class Bean { private String val; private int i; public Bean(String val, int i) { this.val = val; this.i = i; } public String getVal() { return val; } public void setVal(String val) { this.val = val; } public int getI() { return i; } public void setI(int i) { this.i = i; } }
创建测试用例类
创建一个 java 测试类,例如 ParamTestWithDataProvider2.java。