TestNG 快速指南



TestNG - 概述

测试是检查应用程序功能以确保其按要求工作的过程。单元测试在开发人员级别出现,其中采取了充分的措施来测试每个单一实体(类或方法),以确保最终产品满足要求。

与其他任何测试框架相比,JUnit 使开发人员了解测试(尤其是单元测试)的有用性。JUnit 利用相当简单、实用且严格的架构,已经能够“影响”大量的开发人员。请查看我们关于 JUnit 的教程,以了解其功能。同时,JUnit 也有一些缺点,如下所示:

  • 最初设计仅用于启用单元测试,现在用于各种测试。

  • 无法进行依赖性测试。

  • 配置控制较差 (setUp/tearDown)。

  • 侵入式(强制您扩展类并以某种方式命名您的方法)。

  • 静态编程模型(强制您不必要地重新编译)。

  • 在复杂项目中管理不同的测试套件可能非常棘手。

什么是 TestNG?

根据其文档对 TestNG 的定义如下:

TestNG 是一个从 JUnit 和 NUnit 获得灵感的测试框架,但引入了一些新功能,使其功能更强大且更易于使用。

TestNG 是一个开源的自动化测试框架;其中 NG 代表 NextGeneration(下一代)。TestNG 类似于 JUnit(尤其是 JUnit 4),但它不是 JUnit 的扩展。它受到 JUnit 的启发。它旨在比 JUnit 更好,尤其是在测试集成类时。TestNG 的创建者是 Cedric Beust

TestNG 消除了大多数旧框架的局限性,使开发人员能够编写更灵活、更强大的测试。因为它大量借鉴了 Java 注解(JDK 5.0 引入)来定义测试,它还可以向您展示如何在实际生产环境中使用 Java 语言的这一新功能。

TestNG 特性

  • 支持注解。

  • TestNG 使用更多 Java 和面向对象特性。

  • 支持测试集成类(例如,默认情况下,无需为每个测试方法创建新的测试类实例)。

  • 将编译时测试代码与运行时配置/数据信息分开。

  • 灵活的运行时配置。

  • 引入了“测试组”。编译测试后,您可以只要求 TestNG 运行所有“前端”测试,或“快速”、“慢速”、“数据库”测试等。

  • 支持依赖测试方法、并行测试、负载测试和部分失败。

  • 灵活的插件 API。

  • 支持多线程测试。

TestNG - 环境配置

TestNG 是一个 Java 框架,因此首要要求是在您的机器上安装 JDK。

系统需求

JDK 1.5 或更高版本。
内存 无最低要求。
磁盘空间 无最低要求。
操作系统 无最低要求。

步骤 1 - 验证您的机器上是否安装了 Java

打开控制台并根据您在系统上安装的操作系统执行 java 命令。

操作系统 任务 命令
Windows 打开命令控制台 c:\> java -version
Linux 打开命令终端 $ java -version
Mac 打开终端 machine:~ joseph$ java -version

让我们验证所有操作系统的输出:

操作系统 输出
Windows

java version "1.7.0_25"

Java(TM) SE Runtime Environment (build 1.7.0_25-b15)

Java HotSpot(TM) 64-Bit Server VM (build 23.25-b01, mixed mode)

Linux

java version "1.7.0_25"

Java(TM) SE Runtime Environment (build 1.7.0_25-b15)

Java HotSpot(TM) 64-Bit Server VM (build 23.25-b01, mixed mode)

Mac

java version "1.7.0_25"

Java(TM) SE Runtime Environment (build 1.7.0_25-b15)

Java HotSpot(TM) 64-Bit Server VM (build 23.25-b01, mixed mode)

如果您没有 Java,请从 https://www.oracle.com/technetwork/java/javase/downloads/index.html 安装 Java 软件开发工具包 (SDK)。在本教程中,我们假设已安装 Java 1.7.0_25 版本。

步骤 2:设置 JAVA 环境

设置 **JAVA_HOME** 环境变量以指向 Java 安装在您机器上的基目录位置。例如:

操作系统 输出
Windows 将环境变量 JAVA_HOME 设置为 C:\Program Files\Java\jdk1.7.0_25。
Linux Export JAVA_HOME=/usr/local/java-current。
Mac Export JAVA_HOME=/Library/Java/Home。

将 Java 编译器位置添加到系统路径。

操作系统 输出
Windows 在系统变量 Path 的末尾附加字符串 C:\Program Files\Java\jdk1.7.0_25\bin。
Linux Export PATH=$PATH:$JAVA_HOME/bin/
Mac 不需要

使用上面解释的命令 **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
Mac 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 Export TESTNG_HOME=/usr/local/TESTNG
Mac Export TESTNG_HOME=/Library/TESTNG

步骤 5:设置 CLASSPATH 变量

设置 **CLASSPATH** 环境变量以指向 TestNG jar 位置。

操作系统 说明
Windows 将环境变量 CLASSPATH 设置为 %CLASSPATH%;%TESTNG_HOME%\testng-6.8.jar。
Linux Export CLASSPATH=$CLASSPATH:$TESTNG_HOME/testng-6.8.jar。
Mac Export 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 文件。
  • 使用 ANT。
  • 从命令行。

让我们使用 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 文件中添加有关测试的信息(例如类名、要运行的组等)。

  • 运行 TestNG。

在这里,我们将看到一个使用 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

现在使用以下命令运行 TestNG:

C:\TestNG_WORKSPACE>java -cp "C:\TestNG_WORKSPACE" org.testng.TestNG testng.xml

如果一切正确完成,您应该在控制台中看到测试结果。此外,TestNG 在当前目录中自动创建的名为 **test-output** 的文件夹中创建一个非常好的 HTML 报告。如果您打开它并加载 index.html,您将看到类似于下图中的页面:

Writing Tests

TestNG - 基本注解

在 JUnit 3 中指示测试方法的传统方法是在其名称前加上 test。这是一种标记类中某些方法具有特殊含义的非常有效的方法,但命名不能很好地扩展(如果我们想为不同的框架添加更多标记怎么办?)并且相当不灵活(如果我们想传递其他参数到测试框架怎么办?)。

注解在 JDK 5 中正式添加到 Java 语言中,TestNG 选择使用注解来注解测试类。

以下是 TestNG 支持的注解列表:

序号 注解和描述
1

@BeforeSuite

仅在该套件中的所有测试运行之前运行一次。

2

@AfterSuite

仅在该套件中的所有测试运行之后运行一次。

3

@BeforeClass

仅在调用当前类中的第一个测试方法之前运行一次。

4

@AfterClass

仅在当前类中的所有测试方法运行之后运行一次。

5

@BeforeTest

在运行 <test> 标记内的类中的任何测试方法之前运行。

6

@AfterTest

在运行 <test> 标记内的类中的所有测试方法之后运行。

7

@BeforeGroups

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

8

@AfterGroups

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

9

@BeforeMethod

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

10

@AfterMethod

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

11

@DataProvider

将一个方法标记为为测试方法提供数据。带注解的方法必须返回一个 Object[][],其中每个 Object[] 可以赋值给测试方法的参数列表。想要从这个 DataProvider 接收数据的 @Test 方法需要使用一个数据提供程序名称,该名称等于此注解的名称。

12

@Factory

将一个方法标记为一个工厂,该工厂返回 TestNG 将用作测试类的对象。该方法必须返回 Object[]。

13

@Listeners

在测试类上定义监听器。

14

@Parameters

描述如何将参数传递给 @Test 方法。

15

@Test

将类或方法标记为测试的一部分。

使用注解的好处

以下是使用注解的一些好处:

  • 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 注解时使用)。

  • -target

  • -groups

  • -testrunfactory

  • -listener

在下面的示例中,我们将创建一个 TestNG 对象和一个现有的 testng.xml。

创建类

创建一个要测试的 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()。

  • 向 testPrintMessage() 方法添加注解 @Test。

  • 实现测试条件并使用 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 - 套件测试

测试套件是旨在测试软件程序行为或一组行为的测试用例的集合。在 TestNG 中,我们不能在测试源代码中定义套件,但它由一个 XML 文件表示,因为套件是执行的特性。它还允许灵活配置要运行的测试。一个套件可以包含一个或多个测试,并由 <suite> 标签定义。

<suite> 是 testng.xml 的根标签。它描述一个测试套件,该套件又由几个 <test> 部分组成。

下表列出了 <suite> 接受的所有合法属性。

序号 属性 & 描述
1

name

此套件的名称。这是一个必填属性。

2

verbose

此运行的级别或详细程度。

3

parallel

TestNG 是否应该运行不同的线程来运行此套件。

4

thread-count

如果启用了并行模式,则要使用的线程数(否则忽略)。

5

annotations

你在测试中使用的注解类型。

6

time-out

将用于此测试中找到的所有测试方法的默认超时时间。

在本章中,我们将向你展示一个包含两个测试类 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 包含 exampletest1exampletest2

使用 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
===============================================

你还可以检查 test-output 文件夹。在 Suite1 文件夹下,你可以看到创建的两个 html 文件,exampletest1.html 和 exampletest2.html,它们看起来如下:

Writing Tests

Writing Tests

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()。

  • 向 testPrintMessage() 方法添加注解 @Test(enabled = false)。

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 并要求它包含一组特定的组(或正则表达式),同时排除另一组。

组测试在如何划分测试方面提供了最大的灵活性,并且如果要连续运行两组不同的测试,则不需要重新编译任何内容。

组是在你的 testng.xml 文件中使用 <groups> 标签指定的。它可以在 <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 的组 all。让我们修改我们的 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

  • 向 testPrintMessage() 测试用例添加预期的异常 ArithmeticException。

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()。

  • testSalutationMessage() 方法的 @Test 注解中添加属性 dependsOnMethods = {"initEnvironmentTest"}

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
   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”。

  • testSalutationMessage() 方法的 @Test 注解中添加属性 dependsOnMethods = {"init.*"}

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。跳过的 (SKIP) 方法会在最终报告中被这样报告(在 HTML 中显示为既不是红色也不是绿色的颜色),这一点很重要,因为跳过的 (SKIP) 方法不一定是失败。

创建 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
===============================================

dependsOnGroupsdependsOnMethods

  • 使用组后,我们不再受重构问题的影响。只要我们不修改 dependsOnGroups 或 groups 属性,我们的测试将继续以正确的依赖关系设置运行。

  • 每当需要在依赖关系图中添加新方法时,我们只需要将其放入正确的组中,并确保它依赖于正确的组即可。我们不需要修改任何其他方法。

TestNG - 参数化测试

TestNG 的另一个有趣特性是 **参数化测试**。在大多数情况下,你会遇到业务逻辑需要大量不同测试的场景。**参数化测试** 允许开发人员使用不同的值反复运行相同的测试。

TestNG 允许你通过两种不同的方式直接将参数传递给你的测试方法:

  • 使用 testng.xml
  • 使用数据提供者 (Data Providers)

使用 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 中指定的值转换为你的参数类型。以下是支持的类型:

  • String
  • int/Integer
  • boolean/Boolean
  • byte/Byte
  • char/Character
  • double/Double
  • float/Float
  • long/Long
  • short/Short

使用 数据提供者 (Dataproviders) 传递参数

当你需要传递复杂参数或需要从 Java 创建的参数(复杂对象、从属性文件或数据库读取的对象等)时,可以使用数据提供者 (Dataproviders) 传递参数。

数据提供者 (Data Provider) 是使用 @DataProvider 注解的方法。此注解只有一个字符串属性:它的名称。如果未提供名称,则数据提供者的名称将自动默认为方法的名称。数据提供者返回一个对象数组。

以下示例演示如何使用数据提供者。第一个示例是关于使用 Vector、String 或 Integer 作为参数的 @DataProvider,第二个示例是关于使用对象作为参数的 @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()。此方法接受 Integer 和 Boolean 作为输入参数。此方法验证传递的参数是否为素数。

  • 向此方法添加注解 @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

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 = "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 传递 Object 作为参数。

创建 Java 类

创建一个 Java 类 Bean.java,它是一个带有 get/set 方法的简单对象,在 C:\>TestNG_WORKSPACE 中创建。

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。

  • 定义方法 primeNumbers(),该方法使用注解定义为数据提供者。此方法返回一个对象数组。

  • 向你的测试类添加测试方法 testMethod()。此方法接受一个对象 bean 作为参数。

  • 向此方法添加注解 @Test(dataProvider = "test1")。dataProvider 属性映射到 "test1"。

C:\>TestNG_WORKSPACE 中创建一个名为 ParamTestWithDataProvider2.java 的 Java 类文件。

import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;

public class ParamTestWithDataProvider2 {
   @DataProvider(name = "test1")
   public static Object[][] primeNumbers() {
      return new Object[][] { { new Bean("hi I am the bean", 111) } };
   }

   @Test(dataProvider = "test1")
   public void testMethod(Bean myBean) {
      System.out.println(myBean.getVal() + " " + myBean.getI());
   }
}

创建 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 = "ParamTestWithDataProvider2" />
      </classes>
   </test>
</suite>

使用 javac 编译测试用例类。

C:\TestNG_WORKSPACE>javac ParamTestWithDataProvider2.java Bean.java

现在,运行 testng.xml。

C:\TestNG_WORKSPACE>java -cp "C:\TestNG_WORKSPACE" org.testng.TestNG testng.xml

验证输出。

   hi I am the bean 111

===============================================
   Suite1
   Total tests run: 1, Failures: 0, Skips: 0
===============================================

TestNG - 运行 Junit 测试

既然你已经了解了 TestNG 及其各种测试,你可能现在担心如何重构现有的 JUnit 代码。不用担心,TestNG 提供了一种以你自己的速度从 JUnit 切换到 TestNG 的方法。你可以使用 TestNG 执行现有的 JUnit 测试用例。

TestNG 可以自动识别并运行 JUnit 测试,这样你就可以使用 TestNG 作为所有现有测试的运行器,并使用 TestNG 编写新的测试。你只需要将 JUnit 库放在 TestNG 类路径上,以便它可以查找并使用 JUnit 类,在 Ant 中将你的测试运行器从 JUnit 更改为 TestNG,然后以“混合”模式运行 TestNG。这样,你就可以在同一个项目中,甚至同一个包中拥有所有测试,并开始使用 TestNG。这种方法还允许你逐步将现有的 JUnit 测试转换为 TestNG。

让我们来看一个例子来演示 TestNG 的这个惊人功能。

创建 JUnit 测试用例类

创建一个 Java 类,它是一个 JUnit 测试类,TestJunit.java,在 C:\>TestNG_WORKSPACE 中创建。

import org.junit.Test;
import static org.testng.AssertJUnit.assertEquals;

public class TestJunit {
   @Test
   public void testAdd() {
      String str = "Junit testing using TestNG";
      AssertEquals("Junit testing using TestNG",str);
   }
}

现在,让我们在 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 = "Converted JUnit suite" >
   <test name = "JUnitTests" junit="true">
      <classes>
         <class name = "TestJunit" />
      </classes>
   </test>
</suite>
  	

要执行 JUnit 测试用例,请定义属性 junit="true",如上面的 xml 中所示。JUnit 测试用例类 TestJunit 在类名中定义。

对于 JUnit 4,TestNG 将使用 org.junit.runner.JUnitCore 运行器来运行你的测试。

使用 javac 编译所有 Java 类。

C:\TestNG_WORKSPACE>javac TestJunit.java

现在,运行 testng.xml,它将作为 TestNG 运行 JUnit 测试用例。

C:\TestNG_WORKSPACE>java -cp "C:\TestNG_WORKSPACE:C:\TestNG_WORKSPACE\lib\junit-4.11.jar" org.testng.TestNG testng.xml

这里,我们将 junit-4.11.jar 放置在 C:\TestNG_WORKSPACE\lib\junit-4.11.jar 下。

验证输出。

===============================================
   Converted JUnit suite

   Total tests run: 1, Failures: 0, Skips: 0
===============================================

TestNG - 测试结果

报告是任何测试执行中最重要的部分,因为它可以帮助用户了解测试执行的结果、失败点以及失败的原因。另一方面,日志记录对于关注执行流程或在出现任何故障时进行调试非常重要。

TestNG 默认情况下会为其测试执行生成不同类型的报告。这包括 HTML 和 XML 报告输出。TestNG 还允许用户编写自己的报告程序并在 TestNG 中使用它。还有一个选项可以编写你自己的日志记录器,这些日志记录器会在 TestNG 的运行时被通知。

有两种方法可以使用 TestNG 生成报告:

  • 监听器 (Listeners) - 对于实现监听器类,该类必须实现 org.testng.ITestListener 接口。当测试启动、完成、失败、跳过或通过时,TestNG 会在运行时通知这些类。

  • 报告程序 (Reporters) - 对于实现报告类,该类必须实现 org.testng.IReporter 接口。当整个套件运行结束时,会调用这些类。包含整个测试运行信息的类会在调用时传递给此类。

在本章中,我们将有四个不同的例子来演示四种不同的报告和日志记录情况:

序号 案例和示例
1 自定义日志记录

此示例说明如何编写你自己的日志记录器。

2 自定义报告程序

此示例说明如何编写你自己的报告程序。

3 HTML 和 XML 报告

此示例说明 TestNG 生成的默认 HTML 和 XML 报告。

4 JUnit 报告

此示例说明如何从 TestNG 报告生成 JUnit 报告。

TestNG - 与 ANT 集成

在本章中,我们将演示如何使用 ANT 运行 TestNG。让我们按照以下步骤操作:

步骤 1:下载 Apache Ant

下载最新版本的 Apache Ant

操作系统 压缩包名称
Windows apache-ant-1.8.4-bin.zip
Linux apache-ant-1.8.4-bin.tar.gz
Mac apache-ant-1.8.4-bin.tar.gz

步骤 2:设置 Ant 环境

设置 **ANT_HOME** 环境变量,指向 ANT 库在你的计算机上存储的基本目录位置。让我们假设我们将 Ant 库存储在 apache-ant-1.8.4 文件夹中。

操作系统 输出
Windows 将环境变量 ANT_HOME 设置为 C:\Program Files\Apache Software Foundation\apache-ant-1.8.4
Linux Export ANT_HOME=/usr/local/apache-ant-1.8.4
Mac Export ANT_HOME=/Library/apache-ant-1.8.4

将 Ant 编译器位置添加到系统路径,如下所示:

操作系统 说明
Windows 在系统变量 Path 的末尾添加字符串 %ANT_HOME\bin。
Linux Export PATH=$PATH:$ANT_HOME/bin/
Mac 不需要。

步骤 3:下载 TestNG 归档文件

下载所需的 jar 文件 http://www.testng.org

操作系统 归档文件名
Windows testng-6.8.jar
Linux testng-6.8.jar
Mac testng-6.8.jar

步骤 4:创建项目结构

  • C:\>TestNG_WORKSPACE 中创建一个名为 TestNGWithAnt 的文件夹。

  • C:\>TestNG_WORKSPACE>TestNGWithAnt 中创建一个名为 src 的文件夹。

  • C:\>TestNG_WORKSPACE>TestNGWithAnt 中创建一个名为 test 的文件夹。

  • C:\>TestNG_WORKSPACE>TestNGWithAnt 中创建一个名为 lib 的文件夹。

  • C:\>TestNG_WORKSPACE>TestNGWithAnt>src 文件夹中创建 MessageUtil 类。

/*
* 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);
      return message;
   }   

   // add "Hi!" to the message
   public String salutationMessage() {
      message = "Hi!" + message;
      System.out.println(message);
      return message;
   }   
}  	
  • C:\>TestNG_WORKSPACE>TestNGWithAnt>src 文件夹中创建 TestMessageUtil 类。

import org.testng.Assert;
import org.testng.annotations.Test;


public class TestMessageUtil {
   String message = "Manisha";	
   MessageUtil messageUtil = new MessageUtil(message);

   @Test
   public void testPrintMessage() {	
      System.out.println("Inside testPrintMessage()");     
      Assert.assertEquals(message,messageUtil.printMessage());
   }

   @Test
   public void testSalutationMessage() {
      System.out.println("Inside testSalutationMessage()");
      message = "Hi!" + "Manisha";
      Assert.assertEquals(message,messageUtil.salutationMessage());
   }
}
  • 将 testng-6.8.jar 复制到 C:\>TestNG_WORKSPACE>TestNGWithAnt>lib 文件夹。

创建 ANT build.xml

首先,我们需要定义 TestNG Ant 任务,如下所示:

<taskdef name = "testng" classname = "org.testng.TestNGAntTask">
   <classpath>
      <pathelement location = "lib/testng-6.8.jar"/>
   </classpath>
</taskdef>

然后,我们将在 Ant 中使用 <testng> 任务来执行我们的 TestNG 测试用例。

build.xml 文件如下:

<project name = "TestNGTest" default = "test" basedir = ".">

   <!-- Define <testng> task -->

   <taskdef name = "testng" classname = "org.testng.TestNGAntTask">
      <classpath>
         <pathelement location = "lib/testng-6.8.jar"/>
      </classpath>
   </taskdef>

   <property name = "testdir" location = "test" />
   <property name = "srcdir" location = "src" />
   <property name = "libdir" location = "lib" />
   <property name = "full-compile" value="true" />
   
   <path id = "classpath.base"/>
   <path id = "classpath.test">
   
   <fileset dir = "${libdir}">
      <include name = "**/*.jar" />
   </fileset>
   
   <pathelement location = "${testdir}" />
   <pathelement location = "${srcdir}" />
   
   <path refid = "classpath.base" />
   </path>
   
   <target name = "clean" >
      <delete verbose="${full-compile}">
         <fileset dir = "${testdir}" includes="**/*.class" />
      </delete>
   </target>
   
   <target name = "compile" depends="clean">
      <javac srcdir = "${srcdir}" destdir = "${testdir}" verbose="${full-compile}">
         <classpath refid = "classpath.test"/>
      </javac>
   </target>
   
   <target name = "test" depends="compile">
      <testng outputdir = "${testdir}" classpathref="classpath.test"> 
         <xmlfileset dir = "${srcdir}" includes="testng.xml"/> 
      </testng>
   </target>
   
</project>

运行以下 Ant 命令。

C:\TestNG_WORKSPACE\TestNGWithAnt>ant

验证输出。

test:
   [testng] [TestNG] Running:
   [testng]   C:\TestNG_WORKSPACE\TestNGWithAnt\src\testng.xml
   [testng] 
   [testng] Inside testPrintMessage()
   [testng] Manisha
   [testng] Inside testSalutationMessage()
   [testng] Hi!Manisha
   [testng] 
   [testng] ===============================================
   [testng] Plug ANT test Suite
   [testng] Total tests run: 2, Failures: 0, Skips: 0
   [testng] ===============================================
   [testng] 

BUILD SUCCESSFUL
Total time: 1 second

TestNG - 与 Eclipse 集成

要将 TestNG 与 Eclipse 集成,请按照以下步骤操作:

步骤 1:下载 TestNG 压缩包

http://www.testng.org 下载最新版本的 TestNG jar 文件

操作系统 归档文件名
Windows testng-6.8.jar
Linux testng-6.8.jar
Mac testng-6.8.jar

我们假设你已将上述 JAR 文件复制到 C:\>TestNG 文件夹。

步骤 2:设置 Eclipse 环境

  • 打开 Eclipse → 右键单击项目并转到属性 → 构建路径 → 配置构建路径,并使用 添加外部 JAR 按钮将 testng-6.8.jar 添加到库中。

Add testng-6.8.jar in liraries.
  • 我们假设你的 Eclipse 具有内置的 TestNG 插件;如果不可用,请使用更新站点获取最新版本。

    • 在你的 Eclipse IDE 中,选择 帮助/软件更新/查找并安装

    • 搜索要安装的新功能。

    • 新的远程站点。

    • 确保选中 URL 旁边的复选框,然后单击 下一步

    • 然后,Eclipse 将指导你完成此过程。

现在,你的 Eclipse 已准备好开发 TestNG 测试用例。

步骤 3:验证 Eclipse 中 TestNG 的安装

  • 在 Eclipse 中的任何位置创建一个名为 TestNGProject 的项目。

  • 在项目中创建一个名为 MessageUtil 的类进行测试。

/*
* 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;
   }   
} 
  • 在项目中创建一个名为 TestNGExample 的测试类。

   
import org.testng.Assert;
import org.testng.annotations.Test;

public class TestNGExample {
   String message = "Hello World";	
   MessageUtil messageUtil = new MessageUtil(message);

   @Test
   public void testPrintMessage() {	  
      Assert.assertEquals(message,messageUtil.printMessage());
   }
}

项目结构应如下所示:

Project Structure

最后,通过右键单击程序并将其作为 TestNG 运行来验证程序的输出。

验证结果。

TestNG result success.
广告