概述

本指南旨在帮助您将 UI 测试(基于 Selenium WebDriver)集成到现有的 TestNG + Jenkins + 钉钉通知的自动化测试框架中。

1. 技术选型

  • UI 测试框架:Selenium WebDriver 4.x
  • 测试框架:TestNG 7.x
  • 浏览器:Chrome(推荐无头模式)
  • 构建工具:Maven
  • CI/CD:Jenkins
  • 通知:钉钉机器人

2. 项目结构

src/test/
├── java/
│   ├── base/
│   │   └── BaseTest.java          # 公共基类,管理 WebDriver
│   ├── api/
│   │   └── ApiLoginTest.java      # 接口测试示例
│   └── ui/
│       └── UiLoginTest.java       # UI 测试示例
├── resources/
│   ├── testng.xml                 # 测试套件配置
│   └── config.properties          # 配置文件

3. 核心代码示例

3.1 BaseTest.java

package base;

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;

import java.time.Duration;

public class BaseTest {
    protected WebDriver driver;

    @BeforeMethod
    public void setUp() {
        String browser = System.getProperty("browser", "chrome");
        if ("chrome".equalsIgnoreCase(browser)) {
            ChromeOptions options = new ChromeOptions();
            if ("headless".equalsIgnoreCase(browser)) {
                options.addArguments("--headless");
            }
            options.addArguments("--no-sandbox");
            options.addArguments("--disable-dev-shm-usage");
            driver = new ChromeDriver(options);
        }
        // 可扩展其他浏览器
        driver.manage().window().maximize();
        driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));
    }

    @AfterMethod
    public void tearDown() {
        if (driver != null) {
            driver.quit();
        }
    }
}

3.2 UiLoginTest.java

package ui;

import base.BaseTest;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.testng.Assert;
import org.testng.annotations.Test;

public class UiLoginTest extends BaseTest {

    @Test
    public void testLoginSuccess() {
        driver.get("https://example.com/login");
        
        WebElement username = driver.findElement(By.id("username"));
        WebElement password = driver.findElement(By.id("password"));
        WebElement loginBtn = driver.findElement(By.id("login-btn"));

        username.sendKeys("testuser");
        password.sendKeys("password123");
        loginBtn.click();

        // 断言登录成功
        WebElement welcome = driver.findElement(By.id("welcome-message"));
        Assert.assertTrue(welcome.isDisplayed());
    }

    @Test
    public void testLoginFailure() {
        driver.get("https://example.com/login");
        // ... 失败场景测试
    }
}

3.3 ApiLoginTest.java(示例)

package api;

import org.testng.annotations.Test;
import static io.restassured.RestAssured.*;
import static org.hamcrest.Matchers.*;

public class ApiLoginTest {
    
    @Test
    public void testLoginApi() {
        given()
            .contentType("application/json")
            .body("{\"username\":\"test\",\"password\":\"test\"}")
        .when()
            .post("https://api.example.com/login")
        .then()
            .statusCode(200)
            .body("token", notNullValue());
    }
}

4. Maven 依赖

在 pom.xml 中添加以下依赖:

<dependencies>
    <!-- Selenium -->
    <dependency>
        <groupId>org.seleniumhq.selenium</groupId>
        <artifactId>selenium-java</artifactId>
        <version>4.20.0</version>
    </dependency>
    <!-- TestNG -->
    <dependency>
        <groupId>org.testng</groupId>
        <artifactId>testng</artifactId>
        <version>7.8.0</version>
        <scope>test</scope>
    </dependency>
    <!-- RestAssured(接口测试) -->
    <dependency>
        <groupId>io.rest-assured</groupId>
        <artifactId>rest-assured</artifactId>
        <version>5.3.0</version>
        <scope>test</scope>
    </dependency>
</dependencies>

5. 测试套件配置

src/test/resources/testng.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd">
<suite name="All Tests">
    <test name="API Tests">
        <classes>
            <class name="api.ApiLoginTest"/>
        </classes>
    </test>
    <test name="UI Tests">
        <classes>
            <class name="ui.UiLoginTest"/>
        </classes>
    </test>
</suite>

6. Jenkins 流水线调整

6.1 环境准备

  • 在 Jenkins 节点上安装 Chrome 浏览器和 ChromeDriver。
  • 或使用 Docker 容器(推荐 selenium/standalone-chrome)。

6.2 Jenkinsfile 示例

pipeline {
    agent any
    parameters {
        choice(name: 'BROWSER', choices: ['chrome', 'headless'], description: 'Select browser')
        choice(name: 'TEST_SUITE', choices: ['api', 'ui', 'all'], description: 'Test suite to run')
    }
    stages {
        stage('Checkout') {
            steps {
                git url: 'https://github.com/your-repo.git'
            }
        }
        stage('Run Tests') {
            steps {
                script {
                    if (params.TEST_SUITE == 'api' || params.TEST_SUITE == 'all') {
                        sh 'mvn test -Dtest=api.*'
                    }
                    if (params.TEST_SUITE == 'ui' || params.TEST_SUITE == 'all') {
                        sh "mvn test -Dtest=ui.* -Dbrowser=${params.BROWSER}"
                    }
                }
            }
        }
    }
    post {
        always {
            junit 'target/surefire-reports/*.xml'
            archiveArtifacts 'target/screenshots/*.png'
        }
        success {
            // 发送成功通知
            sh 'python scripts/dingtalk_notify.py --status success'
        }
        failure {
            // 发送失败通知
            sh 'python scripts/dingtalk_notify.py --status failure'
        }
    }
}

7. 钉钉通知增强

现有钉钉通知脚本需要解析 testng-results.xml,并区分接口和 UI 测试。建议通知内容包含:

【测试执行结果】
项目:XXX
执行时间:2026-03-04 16:00:00
总用例数:50(接口:30,UI:20)
通过:45
失败:5
成功率:90%
失败用例:
- UiLoginTest.testLoginSuccess (元素未找到)
- ApiLoginTest.testTokenExpired (状态码500)
详细报告:http://jenkins/job/xxx/report

8. 实施路线图

阶段 1:环境准备(1-2 天)

  1. 在本地和 Jenkins 节点安装 Chrome 和 ChromeDriver。
  2. 在 Maven 项目中添加 Selenium 和 TestNG 依赖。
  3. 创建基础目录结构。

阶段 2:编写 UI 测试用例(3-5 天)

  1. 基于现有页面编写 2-3 个关键 UI 测试用例。
  2. 实现 BaseTest 类,支持浏览器管理。
  3. 集成截图功能。

阶段 3:集成到现有框架(2-3 天)

  1. 调整 testng.xml 以包含 UI 测试套件。
  2. 修改钉钉通知脚本,支持 UI 测试结果解析。
  3. 本地验证测试执行和报告。

阶段 4:Jenkins 集成(1-2 天)

  1. 更新 Jenkinsfile,添加 UI 测试阶段。
  2. 配置参数化构建。
  3. 运行完整流水线,确保通知正常。

阶段 5:优化与扩展(持续)

  1. 增加数据驱动测试。
  2. 引入 Page Object 模式。
  3. 添加分布式执行(Selenium Grid)。
  4. 集成 Allure 报告。

9. 常见问题

  1. 浏览器驱动版本不匹配:确保 ChromeDriver 版本与 Chrome 浏览器版本兼容。
  2. 无头模式截图失败:确保在无头模式下启用截图功能。
  3. Jenkins 节点无 GUI:使用无头模式或 Docker 容器。
  4. 测试稳定性:增加显式等待,避免隐式等待超时。

10. 后续建议

  • 考虑使用 Playwright 作为替代方案,以获得更好的稳定性和功能。
  • 将测试数据外部化(Excel/CSV/数据库)。
  • 实现测试用例的版本管理。

完成以上步骤后,您将拥有一个完整的接口 + UI 自动化测试流水线,并能够通过钉钉实时接收测试结果。

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐