Java的TestNG框架和Allure报告

TestNG简介

它是一个单元测试框架,它提供了很多的注解(python装饰器)来帮助我们管理测试用例。

它是Java自动化测试最重要的基石。官网:TestNG Documentation

它在java自动化测试里面主要做什么事情?

发现测试用例

执行测试用例

判断测试结果

生成测试报告

新建一个Maven项目

Interlij lDEA=Pycharm

maven:第三方库,你只需要简单的在pom.xml中配置坐标,就可以自动的从库下载对应的包

如何安装TestNG:

<!--单元测试依赖-->
<dependency>
  <groupId>org.testng</groupId>
  <artifactId>testng</artifactId>
  <version>6.8.7</version>
</dependency>

TestNG使用它最常用的注解

1.测试用例注解:

  • @Test:标识方法是一个基于TestNG的测试用例
  • 常用属性:
    • enabled =false 标识它不是一个测试用例
    • priority=-1 默认的测试用例的执行顺序是基于方法名的ASCIl码,priority可以改变用例的执行顺序,值越小优先级越高。
    • invocationCount=2 控制测试用例的执行次数
      • dependsOnMethods={"方法名”} 解决测试用例之间的依赖关系
    • dependsOnGroups: 指定当前测试方法依赖于哪些组。依赖的组必须先执行。
    • dataProvider 属性来指定数据提供者方法的名称
  • @DataProvider
    • 这个注解用于为测试方法提供参数。
    • 它可以返回一个数组或一个 Iterator,每个元素都是一个参数数组。
  • @Parameters
    • 这个注解用于从命令行参数或配置文件中读取参数。
  • @Factory
    • 这个注解用于创建测试类的实例,可以传递参数给构造函数。
  • @Listeners
    • 这个注解用于指定监听器,监听器可以监听测试的执行并执行自定义逻辑。
  • @DependsOnMethods@DependsOnGroups
    • 这两个注解用于设置测试方法或测试组之间的依赖关系。

2.前后置注解

  • 比如:链接数据库,打开浏览器
    • @BeforeClass@AfterClass(相当于一个子模块)
      • 这两个注解用于在测试类的所有测试方法之前和之后执行代码。
      • @BeforeClass:在所有测试方法执行之前执行一次。
      • @AfterClass:在所有测试方法执行之后执行一次。
      • 在当前测试类中的所有测试方法之前后执行一次。
      • 用于执行类级别的初始化,比如创建共享资源、初始化类变量等。
    • @BeforeMethod@AfterMethod(相当于一个功能)
      • 这两个注解用于在每个测试方法之前和之后执行代码。
      • @BeforeMethod:在每个测试方法执行之前执行。
      • @AfterMethod:在每个测试方法执行之后执行。
      • 在每个测试方法之前后执行。
      • 用于执行每个测试方法的初始化,比如重置测试状态、设置测试输入等。
    • @BeforeTest@AfterTest(相等于一个模块)
      • 这两个注解用于在测试类中的所有测试方法之前和之后执行代码。
      • @BeforeTest:在测试类中的所有测试方法执行之前执行一次。
      • @AfterTest:在测试类中的所有测试方法执行之后执行一次。
      • 在每个测试类(Test)的所有测试方法之前后执行一次。
      • 用于执行测试类级别的初始化,比如设置测试数据、测试环境等。
    • @BeforeSuite@AfterSuite(相当于整个项目)
      • 这两个注解用于在测试套件的所有测试类之前和之后执行代码。
      • @BeforeSuite:在测试套件的所有测试类执行之前执行一次。
      • @AfterSuite:在测试套件的所有测试类执行之后执行一次。
      • 这是最高级别的初始化注解。
      • 在整个测试套件(Suite)的所有测试类和测试方法之前后执行一次。
      • 通常用于执行整个测试套件开始前后需要进行的一次性设置,比如数据库连接、日志配置等。

断言

  1. assertEquals(expected, actual)
    • 检查预期值(expected)和实际值(actual)是否相等。
    • 如果不相等,测试将失败,并显示预期值和实际值。
assertEquals("Expected value", "Actual value");
  1. assertTrue(condition)
    • 检查给定的条件是否为真(boolean true)。
    • 如果条件为假,测试将失败。
assertTrue("Condition should be true", condition);
  1. assertFalse(condition)
    • 检查给定的条件是否为假(boolean false)。
    • 如果条件为真,测试将失败。
assertFalse("Condition should be false", condition);
  1. assertNull(object)
    • 检查给定的对象是否为 null。
    • 如果对象不为 null,测试将失败。
assertNull("Object should be null", object);


批量执行所有用例

使用 TestNG XML 配置文件:

TestNG 允许你创建一个 XML 配置文件来定义测试套件(Suite),其中可以包含多个测试(Test),每个测试可以包含多个测试类(Class)。以下是 XML 配置文件的一个简单示例:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name="MyTestSuite">
  <test name="MyTest">
    <classes>
      <class name="com.example.Test1" />
      <class name="com.example.Test2" />
      <class name="com.example.Test3" />
    </classes>
  </test>
</suite>

然后,你可以使用 testng 命令行工具来执行这个 XML 文件:

testng MyTestSuite.xml

使用 Maven 插件:

如果你的项目是基于 Maven 的,你可以在 pom.xml 文件中添加 TestNG 插件配置,并指定要执行的测试类:

<build>
  <plugins>
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-surefire-plugin</artifactId>
      <version>2.22.2</version>
      <configuration>
        <suiteXmlFiles>
          <suiteXmlFile>src/test/resources/testng.xml</suiteXmlFile>
        </suiteXmlFiles>
      </configuration>
    </plugin>
  </plugins>
</build>

然后,你可以通过执行 mvn test 命令来运行测试。

实现数据驱动(正例和反例)

第一种方法(不可取)

第一步:在testng.xml中定义参数的值:

<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name="DataDrivenTestSuite">
  <test name="DataDrivenTest">
    <parameter name="username" value="user1"/>
    <parameter name="password" value="pass1"/>
    <classes>
      <class name="com.example.DataDrivenTest"/>
    </classes>
  </test>
</suite>

第二步:在测试用例上面通过以下注解来引入参数:

package com.example;

import org.testng.annotations.Parameters;
import org.testng.annotations.Test;

public class DataDrivenTest {

    @Parameters({ "username", "password" })
    @Test
    public void testLogin(String username, String password) {
        // 测试逻辑,使用提供的用户名和密码进行登录
        System.out.println("Testing login with username: " + username + " and password: " + password);
        // 这里应该是实际的登录逻辑和断言
    }
}

3. 执行测试

testng testng.xml

第二种方法

步骤 1: 定义数据提供者方法

首先,你需要定义一个使用 @DataProvider 注解的方法,该方法返回一个二维数组。数组中的每个子数组代表一组测试数据。

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

public class DataDrivenTest {

    // 数据提供者方法
    @DataProvider(name = "dataProvider")
    public Object[][] provideData() {
        // 返回一个二维数组,每个子数组包含一组测试数据
        return new Object[][] {
            {"user1", "password1"},
            {"user2", "password2"},
            {"user3", "password3"}
        };
    }
}

步骤 2: 编写测试方法

接下来,编写测试方法,并使用 @Test 注解的 dataProvider 属性来指定数据提供者方法的名称。测试方法的参数应与数据提供者方法中的数据列对应。

import org.testng.annotations.Test;

public class DataDrivenTest {

    // 数据提供者方法
    @DataProvider(name = "dataProvider")
    public Object[][] provideData() {
        // 返回一个二维数组,每个子数组包含一组测试数据
        return new Object[][] {
            {"user1", "password1"},
            {"user2", "password2"},
            {"user3", "password3"}
        };
    }

    // 测试方法,使用数据提供者
    @Test(dataProvider = "dataProvider")
    public void testLogin(String username, String password) {
        // 这里添加实际的测试逻辑,例如登录验证
        System.out.println("Testing login with username: " + username + " and password: " + password);
        // 假设所有用户都能成功登录,实际测试中应替换为具体的断言
        assert "password".equals(password) : "Login failed for user: " + username;
    }
}

步骤 3: 执行测试

testng DataDrivenTest.java

第三种方法(使用 @Factory 注解)

@Factory 注解可以用来创建测试类的实例,并且每个实例都可以有不同的参数。

import org.testng.annotations.Factory;
import org.testng.annotations.Test;

public class DataDrivenTest {

    String username;
    String password;

    @Factory
    public Object[] createInstances() {
        return new Object[] {
            new DataDrivenTest("user1", "pass1"),
            new DataDrivenTest("user2", "pass2")
            // 更多实例
        };
    }

    public DataDrivenTest(String username, String password) {
        this.username = username;
        this.password = password;
    }

    @Test
    public void testLogin() {
        // 使用 username 和 password 进行测试
    }
}

第四种方法(使用外部数据源)

你可以从外部数据源(如 CSV、Excel、JSON、数据库等)读取数据,并在 @DataProvider 方法中返回这些数据。

import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;

import java.io.FileInputStream;
import java.io.IOException;
import java.util.Iterator;
import java.util.NoSuchElementException;

public class DataProviderFromExcel {

  @DataProvider(name = "excelData")
  public Iterator<Object[]> provideExcelData() throws IOException {
    FileInputStream fis = new FileInputStream(new File("data.xlsx"));
    Workbook workbook = new XSSFWorkbook(fis);
    Sheet sheet = workbook.getSheetAt(0);
    Iterator<Row> rowIterator = sheet.iterator();
    Iterator<Object[]> data = new Iterator<Object[]>() {
      @Override
      public boolean hasNext() {
        return rowIterator.hasNext();
      }

      @Override
      public Object[] next() {
        Row currentRow = rowIterator.next();
        int lastColumn = currentRow.getLastCellNum();
        Object[] dataRow = new Object[lastColumn];
        for (int i = 0; i < lastColumn; i++) {
          Cell cell = currentRow.getCell(i);
          dataRow[i] = cell.getStringCellValue();
        }
        return dataRow;
      }
    };
    return data;
  }

  @Test(dataProvider = "excelData")
  public void testMethod(String[] data) {
    // 测试逻辑
  }
}

第五种方法(使用 Java 8 流和 Lambda 表达式)

如果你使用的是 Java 8 或更高版本,可以利用流(Stream)和 Lambda 表达式来创建数据提供者。

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

import java.util.Arrays;
import java.util.stream.Stream;

public class DataProviderUsingStreams {

  @DataProvider(name = "streamData")
  public static Object[][] provideData() {
    return Stream.of(
      Arrays.asList("user1", "pass1"),
      Arrays.asList("user2", "pass2")
      // 更多数据
    ).map(list -> list.toArray(new Object[0])).toArray(Object[][]::new);
  }

  @Test(dataProvider = "streamData")
  public void testMethod(String username, String password) {
    // 测试逻辑
  }
}

Alure生成精美的测试报告

1.添加依赖

<dependencies>
  <!-- TestNG依赖 -->
  <dependency>
    <groupId>org.testng</groupId>
    <artifactId>testng</artifactId>
    <version>6.14.3</version>
    <scope>test</scope>
  </dependency>
  <!-- Allure TestNG 依赖 -->
  <dependency>
    <groupId>io.qameta.allure</groupId>
    <artifactId>allure-testng</artifactId>
    <version>2.13.5</version>
    <scope>test</scope>
  </dependency>
  <!-- AspectJ依赖 -->
  <dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>1.8.10</version>
  </dependency>
</dependencies>

2.构建allure的插件,AOP拦截测试结果

<build>
    <plugins>
        <!-- 编译插件定义开始 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.1</version>
            <configuration>
                <!-- 设置编译的Java源码版本和目标字节码版本均为1.8 -->
                <source>1.8</source>
                <target>1.8</target>
            </configuration>
        </plugin>
        <!-- 编译插件定义结束 -->
        
        <!-- 测试插件定义开始,用于运行测试并生成Allure测试报告 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>2.22.1</version>
            <configuration>
                <!-- 定义Java代理参数,用于启动AspectJ代理 -->
                <argLine>
                    -javaagent:"${settings.localRepository}/org/aspectj/aspectjweaver/${aspectj.version}/aspectjweaver-${aspectj.version}.jar"
                </argLine>
                <!-- 指定要执行的TestNG测试套件路径 -->
                <suiteXmlFiles>
                    <suiteXmlFile>${suiteXmlFile}</suiteXmlFile>
                </suiteXmlFiles>
                <systemProperties>
                    <property>
                        <!-- 配置Allure测试结果存储路径 -->
                        <name>allure.results.directory</name>
                        <value>${project.build.directory}/allure-results</value>
                    </property>
                </systemProperties>
                <!-- 设置测试出现异常时是否继续执行 -->
                <testFailureIgnore>true</testFailureIgnore>
            </configuration>
            <dependencies>
                <dependency>
                    <groupId>org.aspectj</groupId>
                    <artifactId>aspectjweaver</artifactId>
                    <version>${aspectj.version}</version>
                </dependency>
            </dependencies>
        </plugin>
        <!-- 测试插件定义结束 -->
    </plugins>
</build>

3.生成临时json报告

直接运行testng.xml即可,但是这里有一个问题是每次执行不会自动的清空原来的json报告。

使用 Maven 运行测试用例:(会清空原来的报告)

mvn clean test

这将执行测试用例,并生成 Allure 报告所需的 JSON 结果文件。

4.生成 Allure 报告

测试完成后,在项目根目录下执行以下命令来生成 Allure 报告:

allure generate allure-results -o allure-report

可以使用 Maven 执行以下命令来生成 Allure 报告:

mvn allure:serve

这将在 allure-report 目录下生成 HTML 报告。

5.查看报告

最后,使用以下命令在浏览器中打开生成的 Allure 报告:

allure open allure-report

或者直接打开 allure-report 目录下的 index.html 文件。

通过这些步骤,你可以在 Maven 项目中集成 Allure 并生成精美的测试报告。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值