TestNG 快速入门:核心能力与使用详解

文章目录

  • 前言
  • 一、注解
    • 1.1 什么是注解?
    • 1.2 注解在测试框架中的作用是什么?
  • 二、TestNG 简介
  • 三、TestNG 的主要能力及使用方法
    • 3.1 测试用例管理能力
      • 3.1.1 测试用例定义
      • 3.1.2 测试数据管理(参数化与数据驱动)
      • 3.1.3 依赖管理
    • 3.2 断言能力
      • 3.2.1 硬断言
      • 3.2.2 软断言
    • 3.3 测试用例执行能力
      • 3.3.1 测试生命周期管理
      • 3.3.2 用例组织与编排
      • 3.3.3 并行执行
    • 3.4 测试报告能力
  • 四、总结


前言

在自动化测试中,我们必须依赖某种工具来编写测试用例、验证测试结果、执行测试用例,这种工具就叫做测试框架。基于不同的开发语言,常用的测试框架有如下几类:

框架 语言 用途
JUnit Java 主要用于 Java 代码的单元测试,是 Java 生态中最常用的单元测试框架
TestNG Java TestNG 是 JUnit 的 “增强升级版”,继承了 JUnit 的基础功能(如注解语法),但通过扩展特性(数据驱动、分组依赖、并行执行等)覆盖了更复杂的测试场景。适合大型项目和复杂测试场景
Pytest Python 可用于 Python 项目的单元测试、功能测试、集成测试等各种测试场景
NUnit C# 主要用于 .NET 平台的单元测试和集成测试。

各类测试框架的能力和知识点其实都是相通的。本文就以TestNG为例,为大家介绍测试框架的核心能力和使用方法。

一、注解

注解是测试框架的核心机制之一,要讲测试框架就离不开注解,我们先来看看注解的定义和作用。

1.1 什么是注解?

技术定义: 注解(Annotation)是一种代码元数据,用于为程序提供额外的描述性信息。这些信息不直接影响代码逻辑,但可以在编译、类加载、运行时被工具(如编译器、测试框架、IDE)读取和使用,从而实现特定功能(如配置、标记、约束等)。

白话解释: 你可以把注解想象成是代码里的小标签。就好比你在生活中,会给不同的物品贴上标签来表明它们的用途、特点或者一些额外的说明。编译器、测试框架或者其他工具会通过这些标签,对被贴标签的内容做一些特殊处理。

注解的核心特点:
声明方式: 通常以 @ 符号开头(如 Java 中的 @Test、Python 中的 @pytest.mark),后跟注解名称和参数。
作用范围: 可作用于类、方法、变量、参数等。
生命周期: 部分注解仅在编译期有效(如 @Override),部分可在运行时读取(如测试框架中的注解)。

1.2 注解在测试框架中的作用是什么?

注解是测试框架的 “粘合剂”,其核心思想是:通过元数据驱动测试流程。它通过 声明式语法 简化测试逻辑,实现测试用例的自动化识别、配置、分组、参数化等功能。

如:
@Test注解: 它就像一个 “测试标记笔”。测试框架要知道哪些代码是用来做测试的,哪些不是。通过在方法或者类上加上@Test,就可以清楚地告诉测试框架:“这个方法或者类是一个测试用例,你要去执行它”

@BeforeTest/@AfterTest注解: 用来配置测试的一些条件,比如在测试执行前后要做什么事情。这就好比你在做一件事情之前要先准备好工具,做完之后要把工具收拾好。

@DataProvider注解: 有时候一个测试用例需要用不同的数据来测试,@DataProvider可以帮助实现这个功能,就像给测试用例提供不同的 “食材”。

二、TestNG 简介

TestNG(Testing Next Generation)是一个受 JUnit 和 NUnit 启发而设计的测试框架,旨在为开发者提供更强大、更灵活的测试解决方案。它支持测试用例分组和依赖管理、数据驱动测试、并行执行测试用例等,能够满足复杂场景下的测试需求。

作为一个测试框架,TestNG提供了几大类的基本能力:测试用例管理能力、断言能力、测试执行能力、测试报告能力。下面我们为大家详细介绍每种能力的具体使用方法。

三、TestNG 的主要能力及使用方法

3.1 测试用例管理能力

3.1.1 测试用例定义

在 TestNG 中,我们使用 @Test 注解来定义测试用例。通过@Test注解,我们告诉测试框架:“这个方法或者类是一个测试用例,你要去执行它”。

以下是一个简单的示例:

`import org.testng.annotations.Test;

public class TestCaseDefinitionExample {
    @Test
    public void testAddition() {
        int a = 2;
        int b = 3;
        int result = a + b;
        Assert.assertEquals(result , 5);
    }
}`

在上述代码中,@Test 注解标记了 testAddition 方法为一个测试用例。当我们运行这个测试类时,TestNG 会自动执行该方法。

3.1.2 测试数据管理(参数化与数据驱动)

TestNG 支持参数化测试,我们可以使用 @DataProvider 注解来为测试用例提供测试数据。以下是一个示例:

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

public class DataDrivenTestingExample {
    //定义名称为testData的数据提供者
    @DataProvider(name = "testData")
    public Object[][] provideTestData() {
        return new Object[][]{
                {2, 3, 5},
                {4, 5, 9}
        };
    }

    //使用名称为testData的数据提供者来为测试用例传入测试数据
    @Test(dataProvider = "testData")
    public void testAddition(int a, int b, int expected) {
        int result = a + b;
        Assert.assertEquals(result , expected);
    }
}

在上述代码中,@DataProvider 注解定义了一个名为 testData 的数据提供者,它返回一个二维数组,包含多组测试数据。@Test 注解的 dataProvider 属性指定了使用testData数据提供者,这样 testAddition 方法会针对每组数据执行一次。

3.1.3 依赖管理

TestNG 允许我们定义测试用例之间的依赖关系,使用 @Test注解中的dependsOnMethods 或 dependsOnGroups 属性来实现测试用例之间的依赖关系定义。以下是一个示例:

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

public class DependencyManagementExample {
    @Test
    public void testLogin() {
        // 模拟登录测试
        System.out.println("Login successful");
    }

    /*testCreateOrder依赖于testLogin*/
    @Test(dependsOnMethods = "testLogin")
    public void testCreateOrder() {
        // 模拟创建订单测试
        System.out.println("Order created");
    }
}

在上述代码中,testCreateOrder 方法依赖于 testLogin 方法,只有当 testLogin 方法执行成功后,testCreateOrder 方法才会执行。

3.2 断言能力

TestNG 提供了丰富的断言方法,用于自动验证测试结果,包括硬断言和软断言。

硬断言: 是一种当断言条件不满足时,会立即终止当前测试用例执行的断言方式。一旦硬断言失败,测试框架会认为该测试用例执行失败,并且不会继续执行该测试用例中后续的代码。
软断言:软断言是当断言条件不满足时,不会立即终止当前测试用例的执行,而是会记录下该断言失败的信息,继续执行测试用例中后续的代码。直到测试用例执行完毕,才会将所有软断言的失败信息汇总并报告。

3.2.1 硬断言

  1. assertEquals
    用于比较两个值是否相等。如果不相等,测试将失败。
import org.testng.Assert;
import org.testng.annotations.Test;

public class AssertionExample {
    @Test
    public void testEquality() {
        int result = 2 + 2;
        Assert.assertEquals(result, 4, "2 + 2 应该等于 4");
    }
}
  1. assertTrue 和 assertFalse
    assertTrue用于验证一个布尔表达式是否为true,assertFalse则用于验证是否为false。
import org.testng.Assert;
import org.testng.annotations.Test;

public class BooleanAssertionExample {
    @Test
    public void testTrue() {
        boolean condition = 5 > 3;
        Assert.assertTrue(condition, "5 应该大于 3");
    }

    @Test
    public void testFalse() {
        boolean condition = 2 < 1;
        Assert.assertFalse(condition, "2 不应该小于 1");
    }
}
  1. assertNull 和 assertNotNull
    assertNull用于验证一个对象是否为null,assertNotNull则用于验证对象不为null。
import org.testng.Assert;
import org.testng.annotations.Test;

public class NullAssertionExample {
    @Test
    public void testNull() {
        String str = null;
        Assert.assertNull(str, "str 应该为 null");
    }

    @Test
    public void testNotNull() {
        String str = "test";
        Assert.assertNotNull(str, "str 不应该为 null");
    }
}

3.2.2 软断言

import org.testng.annotations.Test;
import org.testng.asserts.SoftAssert;

public class SoftAssertionExample {
    @Test
    public void testSoftAssertions() {
        SoftAssert softAssert = new SoftAssert();

        int result1 = 2 + 2;
        softAssert.assertEquals(result1, 5, "2 + 2 应该等于 5(故意设置错误)");

        boolean condition = 5 < 3;
        softAssert.assertTrue(condition, "5 应该小于 3(故意设置错误)");

        softAssert.assertAll();
    }
}

在上述示例中,即使前两个断言失败,测试方法也会继续执行,直到调用assertAll方法时,才会将所有的失败信息一并报告。软断言在一个测试方法中需要进行多个断言的场景下非常有用,可以一次性获取所有的断言失败信息,方便调试。

3.3 测试用例执行能力

在 TestNG 框架中,testng.xml是测试执行的指挥官,能对测试的执行过程进行灵活且精细的控制。所以在介绍测试执行之前,先来看看testng.xml文件的基本组成。



<suite name="FullTestSuite" parallel="methods" thread-count="3">
    
    
    <parameter name="baseUrl" value="https://example.com"/>

    
    
    <test name="SampleTest">
        
        <groups>
            
            <run>
                
                <include name="smoke"/>
                
                <exclude name="slow"/>
            run>
        groups>

        
        <classes>
            
            
            <class name="com.example.TestClass1"/>
            <class name="com.example.TestClass2"/>
        classes>
    test>

    
    <test name="AnotherTest">
        <classes>
            <class name="com.example.TestClass3"/>
        classes>
    test>
suite>   

3.3.1 测试生命周期管理

TestNG 提供了多个注解来管理测试的生命周期,通过这些注解定义其被标注的方法在什么阶段运行。

1. 套件级别注解:作用范围是TestNG中的 < suite >标签
@BeforeSuite:在整个测试套件开始执行之前运行,通常用于执行一些全局的初始化操作,比如数据库连接、配置文件加载等。
@AfterSuite:在整个测试套件执行完毕之后运行,用于进行全局的清理工作,例如关闭数据库连接、释放资源等。

2. 测试级别注解:作用范围是TestNG中的 < test > 标签
@BeforeTest:在 标签内的任何测试开始执行之前运行,该注解可用于对每个 进行独立的初始化。
@AfterTest:在 标签内的所有测试执行完毕之后运行,用于清理测试执行后产生的临时数据或资源。

3. 组级别注解:作用范围是TestNG 中的 < groups > 标签
@BeforeGroups:在< groups >标签内的任何测试用例执行之前运行,用于对特定组的测试用例进行前置准备。
@AfterGroups:在< groups >标签内的所有测试用例执行完毕之后运行,用于清理特定组测试用例执行后产生的资源。

4. 类级别注解:作用范围是 Java 的类
@BeforeClass:在当前测试类的第一个测试方法执行之前运行,通常用于对测试类进行初始化,比如创建测试对象等。
@AfterClass:在当前测试类的所有测试方法执行完毕之后运行,用于清理测试类执行过程中产生的资源。

5. 方法级别注解:作用范围是 每个测试方法
@BeforeMethod:在每个测试方法执行之前运行,可用于为每个测试方法提供独立的初始化环境。
@AfterMethod:在每个测试方法执行完毕之后运行,用于清理每个测试方法执行后产生的临时数据。

6. 测试方法注解
@Test:用于标记一个方法为测试方法,TestNG 会执行被该注解标记的方法。

当执行一个 TestNG 测试时,上述注解的执行顺序如下:

@BeforeSuite
    @BeforeTest
        @BeforeGroups
            @BeforeClass
                @BeforeMethod
                    @Test
                @AfterMethod
            @AfterClass
        @AfterGroups
    @AfterTest
@AfterSuite

3.3.2 用例组织与编排

1. 我们可以使用 groups 属性对测试用例进行分组,然后通过 testng.xml 文件来筛选执行特定组的测试用例。
以下是一个示例:

import org.testng.annotations.Test;

public class TestCaseGroupingExample {
    @Test(groups = "smoke")
    public void testSmoke() {
        System.out.println("Executing smoke test");
    }

    @Test(groups = "regression")
    public void testRegression() {
        System.out.println("Executing regression test");
    }
}

以下是对应的 testng.xml 文件, testng.xml 文件指定只执行 smoke 组的测试用例:

DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="GroupSuite">
    <test name="GroupTest">
        <groups>
            <run>
                <include name="smoke"/>
            run>
        groups>
        <classes>
            <class name="com.example.TestCaseGroupingExample"/>
        classes>
    test>
suite>

2. 我们可以使用@test注解的 priority 属性来指定测试用例的执行优先级。priority 属性是一个整数,数值越小,优先级越高。
以下是一个示例:

import org.testng.annotations.Test;

public class PriorityExample {
    @Test(priority = 2)
    public void testMethod2() {
        System.out.println("Executing test method 2");
    }

    @Test(priority = 1)
    public void testMethod1() {
        System.out.println("Executing test method 1");
    }

    @Test(priority = 3)
    public void testMethod3() {
        System.out.println("Executing test method 3");
    }
}

在上述示例中,testMethod1 的优先级最高,会最先执行,接着是 testMethod2,最后是 testMethod3。如果不指定 priority 属性,TestNG 会按照方法的字母顺序执行测试用例。

3.3.3 并行执行

TestNG 支持并行执行测试用例,我们可以通过配置 testng.xml 文件来实现。以下是一个示例 testng.xml 文件:

DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="ParallelSuite" parallel="methods" thread-count="2">
    <test name="ParallelTest">
        <classes>
            <class name="com.example.TestClass1"/>
            <class name="com.example.TestClass2"/>
        classes>
    test>
suite>

在上述配置中,parallel=“methods” 表示并行执行测试方法,thread-count=“2” 表示使用 2 个线程进行并行执行。

3.4 测试报告能力

TestNG 会自动生成测试报告,默认情况下,测试报告位于 test-output 目录下。我们可以使用不同的插件来生成更美观、详细的测试报告,如 Allure 报告。以下是配置 Allure 报告的步骤:

  1. 安装 Allure 命令行工具。
  2. 在 pom.xml 中添加 Allure TestNG 依赖:
<dependency>
    <groupId>io.qameta.alluregroupId>
    <artifactId>allure-testngartifactId>
    <version>2.21.0version>
dependency>
  1. 在 testng.xml 中添加 Allure 监听器:
xml
DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="AllureSuite">
    <listeners>
        <listener class-name="io.qameta.allure.testng.AllureTestNg"/>
    listeners>
    <test name="AllureTest">
        <classes>
            <class name="com.example.TestClass"/>
        classes>
    test>
suite>
  1. 运行测试后,使用 Allure 命令行工具生成报告:
allure generate allure-results --clean -o allure-report
allure open allure-report

四、总结

TestNG 是一个功能强大、灵活的 Java 测试框架,它提供了丰富的测试用例管理、断言、用例执行和测试报告能力。通过本文的介绍和示例,相信新手开发者已经对 TestNG 的主要能力和使用方法有了初步的了解。在实际项目中,合理运用 TestNG 的这些能力,可以提高测试效率,确保软件质量。
希望本文对你有所帮助,祝你在测试工作中取得更好的成果!

你可能感兴趣的:(软件测试,测试工具)