1. 概述
从自然语言到测试脚本的自动化
测试脚本智能生成是AI辅助测试中最具生产力的方向之一。借助大语言模型(LLM)对自然语言的理解能力和代码生成能力,测试人员可以用中文/英文描述测试场景,AI自动将其转换为可执行的测试脚本。这一能力使得“说人话就能写脚本”成为现实,大幅降低了自动化测试的门槛。
典型的流程如下:
- 描述意图:测试人员用自然语言描述测试目标与步骤(如“打开登录页,输入用户名admin和密码123456,点击登录按钮,验证跳转到首页”)
- AI解析:LLM解析语义,识别页面元素、操作类型、断言条件
- 框架映射:将语义操作映射为目标测试框架的API(如Selenium的
find_element、Playwright的page.locator) - 脚本输出:生成结构完整、可直接运行的测试脚本,包含必要的import、setup/teardown、断言
传统脚本开发的痛点
| 痛点 | 传统方式 | AI辅助方式 |
|---|---|---|
| 学习成本高 | 测试人员需掌握编程语言 + 测试框架 + DOM/XPath定位 | 自然语言描述即可,AI处理技术细节 |
| 编写效率低 | 手写脚本,逐行调试,一个登录场景可能需要30-60分钟 | 分钟级生成初版脚本,人工微调即可 |
| 元素定位脆弱 | 依赖人工编写XPath/CSS选择器,前端变更后大量失效 | AI可生成多种备选定位策略,自动推荐最稳健的方案 |
| 框架迁移困难 | 从Selenium迁到Playwright需重写全部脚本 | AI可辅助跨框架转换,保留测试逻辑 |
| 维护成本高 | 需求变更后需人工逐条修改脚本 | 描述新需求,AI批量更新相关脚本 |
| 代码风格不一致 | 多人协作编写,风格各异,难以维护 | AI按统一模板和规范生成,风格一致 |
2. 核心技术方法
2.1 自然语言描述 → 脚本
这是最直接、最常用的AI脚本生成模式。测试人员用结构化的自然语言描述测试场景,LLM负责将其转换为代码。描述越精确、上下文越充分,生成质量越高。
示例:将中文描述转为 Playwright 脚本
输入描述:
测试场景:用户登录功能验证
前提条件:用户已在登录页面(https://example.com/login)
测试步骤:
1. 在用户名输入框(id=username)中输入 "testuser"
2. 在密码输入框(id=password)中输入 "Test@123"
3. 点击"登录"按钮(id=login-btn)
4. 验证页面跳转到 /dashboard
5. 验证页面包含文字 "欢迎回来"
AI生成的Playwright脚本:
import { test, expect } from '@playwright/test';
test('用户登录功能验证', async ({ page }) => {
// 打开登录页面
await page.goto('https://example.com/login');
// 输入用户名和密码
await page.fill('#username', 'testuser');
await page.fill('#password', 'Test@123');
// 点击登录按钮
await page.click('#login-btn');
// 验证页面跳转到 /dashboard
await expect(page).toHaveURL(/\/dashboard/);
// 验证页面包含欢迎文字
await expect(page.locator('body')).toContainText('欢迎回来');
});
data-testid属性作为元素标识,与前端约定规范。
2.2 录制回放增强
传统录制回放工具(如Selenium IDE、Playwright Codegen)能记录用户操作并生成线性脚本,但生成的脚本往往存在以下问题:
- 定位器脆弱(使用绝对XPath或CSS层级),前端微调即失效
- 脚本线性无结构,缺乏Page Object封装
- 缺少有意义的断言,仅记录操作不验证结果
- 重复代码多,不符合DRY原则
AI增强方案:将录制生成的原始脚本作为输入,LLM对其进行智能优化:
- 定位器优化:从脆弱的XPath转为语义化定位(优先使用
data-testid、role、text等) - 结构化重构:自动提取Page Object模式,封装页面元素和操作
- 断言补全:根据操作上下文智能添加验证断言
- 公共步骤抽取:识别重复操作(如登录前置),抽取为公共fixture/fixture
2.3 跨框架转换
当团队决定进行测试框架迁移时(例如从Selenium迁移到Playwright,或从JUnit迁移到pytest),AI可以显著降低迁移成本。只需将现有脚本作为上下文提供给LLM,即可生成目标框架的等效脚本。
支持的典型转换场景
| 源框架 | 目标框架 | 转换要点 |
|---|---|---|
| Selenium (Java) | Playwright (TypeScript) | API映射、异步处理、自动等待机制替换显式等待 |
| Selenium (Python) | Playwright (Python) | 定位策略迁移、断言API替换、浏览器上下文管理 |
| Cypress | Playwright | 链式调用转async/await、cy.xxx() API映射 |
| JUnit 4 | JUnit 5 / pytest | 注解转换、参数化测试迁移、断言库替换 |
| Robot Framework | pytest + Playwright | 关键字驱动→函数式、变量作用域转换 |
| Postman Collection | Python requests / JS axios | HTTP请求→代码、环境变量处理、断言转换 |
2.4 数据驱动脚本生成
数据驱动测试(DDT)将测试逻辑与测试数据分离,是提升测试覆盖率和可维护性的关键模式。AI可以帮助:
- 模板生成:根据测试场景生成参数化的脚本模板
- 数据文件生成:自动生成JSON/CSV/YAML格式的测试数据文件
- 边界数据构造:基于等价类和边界值分析方法,自动生成覆盖边界条件的数据组合
示例:pytest参数化脚本
输入描述:"生成一个登录功能的参数化测试,覆盖正常登录、空用户名、空密码、错误密码、SQL注入尝试5种场景"
import pytest
# 测试数据
login_test_data = [
("admin", "Admin@123", True, "正常登录"),
("", "Admin@123", False, "空用户名"),
("admin", "", False, "空密码"),
("admin", "wrongpass", False, "错误密码"),
("admin' OR '1'='1", "admin", False, "SQL注入尝试"),
]
@pytest.mark.parametrize("username,password,should_succeed,description", login_test_data)
def test_login(username, password, should_succeed, description, page):
"""登录功能参数化测试"""
page.goto("https://example.com/login")
page.fill("#username", username)
page.fill("#password", password)
page.click("#login-btn")
if should_succeed:
# 成功登录:应跳转到首页
assert page.url.endswith("/dashboard"), f"测试场景 [{description}] 失败:未跳转到首页"
expect(page.locator(".welcome")).to_be_visible()
else:
# 登录失败:应停留在登录页并显示错误提示
assert "/login" in page.url, f"测试场景 [{description}] 失败:页面不应跳转"
expect(page.locator(".error-message")).to_be_visible()
3. 支持的主流框架和语言
3.1 支持的语言
当前主流LLM在以下编程语言的测试脚本生成上表现良好:
| 语言 | 生成质量 | 适用场景 | 推荐框架 |
|---|---|---|---|
| Python | ⭐ 极高 | 通用自动化测试、API测试、数据测试 | pytest, Playwright, Selenium, requests |
| TypeScript/JavaScript | ⭐ 极高 | 前端E2E测试、Node.js后端测试 | Playwright, Cypress, Jest, Vitest |
| Java | ⭐ 高 | 企业级应用测试、Spring Boot集成测试 | JUnit 5, TestNG, Selenium, RestAssured |
| Go | ⭐ 中高 | 微服务测试、性能测试 | testing, testify, GoDog |
| C# | ⭐ 中高 | .NET生态测试 | NUnit, xUnit, Playwright.NET |
| Ruby | ⭐ 中 | Rails应用测试 | RSpec, Capybara |
3.2 支持的框架对比
| 框架 | 类型 | AI生成友好度 | 优势 | 不足 |
|---|---|---|---|---|
| Playwright | UI E2E | ⭐⭐⭐⭐⭐ | API设计现代,自动等待,多浏览器,内置断言 | 生态较新,部分企业还在迁移中 |
| Selenium | UI E2E | ⭐⭐⭐⭐ | 生态成熟,社区资源丰富,支持语言多 | 需手动管理等待,脚本冗长 |
| Cypress | UI E2E | ⭐⭐⭐⭐ | 实时重载,调试体验好 | 仅支持JS/TS,跨域限制 |
| Appium | 移动端UI | ⭐⭐⭐ | 跨平台移动测试,支持原生/混合/H5 | 脚本较复杂,定位策略多样 |
| pytest | 通用/API | ⭐⭐⭐⭐⭐ | 参数化强大,插件生态好,fixture机制灵活 | 仅Python |
| JUnit 5 | 通用/API | ⭐⭐⭐⭐ | Java生态标准,参数化测试,扩展模型 | 配置相对复杂 |
| JMeter | 性能测试 | ⭐⭐⭐ | GUI配置,分布式压测,插件丰富 | AI生成XML脚本较难,建议生成辅助代码 |
3.3 API测试脚本生成
AI在API测试脚本生成方面表现尤为突出。常见场景包括:
- Postman Collection → Python/Java代码:将Postman导出为JSON collection,LLM解析后生成等价代码
- OpenAPI/Swagger → 测试脚本:根据API规范自动生成覆盖各类状态码和参数的测试用例
- cURL命令 → 代码:将cURL命令转换为Python requests、Java OkHttp等代码
示例:Postman请求 → Python requests
输入(Postman导出的请求描述):
POST https://api.example.com/v1/users
Headers:
Content-Type: application/json
Authorization: Bearer {{token}}
Body:
{
"username": "newuser",
"email": "newuser@example.com",
"role": "viewer"
}
AI生成的pytest脚本:
import requests
import pytest
BASE_URL = "https://api.example.com/v1"
@pytest.fixture
def auth_token():
"""获取认证Token"""
resp = requests.post(f"{BASE_URL}/auth/login", json={
"username": "admin",
"password": "Admin@123"
})
return resp.json()["token"]
def test_create_user_success(auth_token):
"""测试创建用户 - 正常场景"""
headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {auth_token}"
}
payload = {
"username": "newuser",
"email": "newuser@example.com",
"role": "viewer"
}
resp = requests.post(f"{BASE_URL}/users", headers=headers, json=payload)
# 验证响应
assert resp.status_code == 201, f"期望201,实际 {resp.status_code}"
data = resp.json()
assert data["username"] == payload["username"]
assert data["email"] == payload["email"]
assert "id" in data, "响应应包含用户ID"
4. 脚本质量保证
4.1 脚本可维护性检查
AI生成的脚本虽然功能上可能正确,但在可维护性方面需要额外关注。以下是关键检查维度:
- 元素定位策略:是否使用了稳健的定位器(优先
data-testid>id>role>text>CSS>XPath) - 等待策略:是否依赖固定sleep?Playwright的自动等待是否被正确利用?
- 代码复用:常用操作是否封装为Page Object或fixture?
- 环境隔离:URL、凭据等是否硬编码?是否支持多环境配置?
- 错误处理:失败时是否有清晰的错误信息和截图?
4.2 AI产生的常见脚本问题
| 问题类型 | 表现 | 风险 | 修复建议 |
|---|---|---|---|
| 假断言(Fake Assertion) | assert True、assert 1==1等无意义断言 | 脚本“通过”但实际未验证任何业务逻辑 | 逐条检查断言是否与测试目标直接相关 |
| 遗漏验证点 | 只验证了跳转URL,未验证页面内容/状态 | 浅层验证,漏掉关键业务缺陷 | 补充业务状态验证(如元素可见性、数据正确性) |
| 定位器过拟合 | 使用完整CSS路径如 div:nth-child(3) > span:nth-child(2) | UI微调即导致定位失败 | 改用语义化属性定位 |
| 硬编码等待 | 大量 time.sleep(3) 或 Thread.sleep(3000) | 脚本执行慢、不稳定 | 改用智能等待(waitForSelector、waitForResponse) |
| 缺少清理步骤 | 测试创建了数据但未在teardown中清理 | 测试数据污染环境,影响后续执行 | 添加fixture teardown或清理脚本 |
| 幻觉API调用 | 调用了不存在的函数或错误的参数名 | 脚本无法运行 | 实际运行验证,参考官方API文档 |
4.3 代码风格一致性
在团队协作中,保持代码风格一致对于可维护性至关重要。建议通过以下方式确保AI生成脚本的风格统一:
- 提供风格参考:在Prompt中附上团队现有的测试脚本样例,让AI学习风格
- 配置Linter:使用ESLint / Pylint / Checkstyle对生成脚本自动检查
- 统一模板:定义团队级脚本模板(文件头注释、命名规范、目录结构)
- Code Review:AI生成的脚本同样需要走Code Review流程
4.4 脚本审查清单
| 序号 | 审查项 | 标准 | 优先级 |
|---|---|---|---|
| 1 | 脚本能否直接运行 | 复制到项目中无需额外修改即可执行 | P0 |
| 2 | 测试目的是否明确 | 函数名/描述清晰表达测试场景 | P0 |
| 3 | 断言是否有效 | 每个断言验证一个明确的业务预期 | P0 |
| 4 | 元素定位是否稳健 | 优先使用语义化定位,避免脆弱选择器 | P1 |
| 5 | 是否包含必要的等待 | 使用智能等待,无硬编码sleep | P1 |
| 6 | 是否有环境配置 | URL/凭据通过配置文件或环境变量注入 | P1 |
| 7 | 是否有数据清理 | 测试创建的数据在teardown中清理 | P1 |
| 8 | 错误信息是否友好 | 失败时提供上下文信息(截图、日志) | P2 |
| 9 | 是否符合代码规范 | 通过Linter检查,风格与团队一致 | P2 |
| 10 | 是否有独立运行能力 | 脚本不依赖特定执行顺序,可单独运行 | P2 |
5. 银行业自动化脚本实践
5.1 银行系统的UI自动化挑战
银行系统的UI自动化测试面临独特的挑战,这些挑战使得AI辅助脚本生成更具价值,同时也对生成的脚本质量提出了更高要求:
- 安全控件:银行登录页常使用自定义密码键盘、软键盘,标准定位方式失效
- 验证码:图形验证码、短信验证码阻碍自动化流程,需要测试环境配合绕过或使用固定验证码
- 多因素认证:UKey、生物识别、动态口令等因素增加脚本复杂度
- iframe嵌套:支付网关、网银控件常通过多层iframe嵌入,增加了元素定位难度
- 前端框架差异:银行系统可能使用较老的技术栈(如IE兼容模式、ActiveX控件)
5.2 AI辅助脚本适配银行系统
AI在适应银行系统的特殊控件方面可以发挥独特作用:
- 智能定位推断:当标准HTML元素不可用时,AI可根据上下文推断备用定位策略
- 自定义组件封装:AI可以帮助生成银行自定义控件(如金额输入框、日期选择器)的Page Object封装
- 会话管理:AI可生成复杂登录流程脚本(包括多因素认证、Session保持)
- 协议适配:对于非HTTP协议(如SWIFT、银联8583),AI可生成协议编解码层的测试辅助代码
5.3 性能测试脚本的AI生成
AI在性能测试脚本生成方面同样具有潜力。通过描述压测场景,AI可生成JMeter可导入的脚本片段或辅助Python代码。
- 场景描述 → 压测计划:描述“对转账接口进行梯度压测,从100并发逐步增加到1000,每步持续5分钟”
- 流量建模辅助:根据生产日志分析,AI推荐压测模型参数
- 断言生成:为JMeter脚本自动生成响应断言和JSON断言
5.4 与JMeter脚本结合实践
结合实际的JMeter实践经验,AI可以在以下环节提供帮助:
| 环节 | AI辅助方式 | 实际价值 |
|---|---|---|
| 测试计划生成 | 根据需求文档生成JMeter .jmx文件基础结构 | 减少手工搭建线程组、配置元件的时间 |
| 参数化配置 | 自动生成CSV Data Set Config的数据模板和变量引用 | 快速构建数据驱动的压测场景 |
| 预处理/后处理脚本 | 生成Beanshell/Groovy脚本处理动态参数(签名加密、Token获取) | 解决银行接口常见的签名鉴权问题 |
| 结果断言 | 自动生成JSON断言和响应断言规则 | 确保压测不仅看TPS,也验证业务正确性 |
| 压测报告分析 | 分析JMeter HTML报告,生成自然语言结论和建议 | 快速定位性能瓶颈 |
| 脚本迁移 | JMeter .jmx → Locust Python脚本转换 | 从GUI工具迁移到代码化压测框架 |
JMeter Beanshell脚本生成示例
需求:“生成一个JMeter Beanshell预处理脚本,对请求体进行MD5签名,并将签名放入Header的X-Signature字段”
import java.security.MessageDigest;
import org.apache.commons.codec.binary.Hex;
// 获取请求体
String requestBody = sampler.getArguments().getArgument(0).getValue();
// MD5签名
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] digest = md.digest(requestBody.getBytes("UTF-8"));
String signature = Hex.encodeHexString(digest);
// 设置Header
sampler.getHeaderManager().add(new org.apache.jmeter.protocol.http.control.Header(
"X-Signature", signature
));
// 日志输出(调试用)
log.info("Generated signature: " + signature);
6. 工具链推荐
6.1 主流AI编码工具的测试脚本能力对比
| 工具 | 测试脚本生成能力 | 优势 | 局限 |
|---|---|---|---|
| GitHub Copilot | ⭐⭐⭐⭐⭐ | IDE深度集成,上下文感知强,支持多语言多框架 | 需付费,企业内部代码安全顾虑 |
| Cursor | ⭐⭐⭐⭐⭐ | 基于VS Code,支持整个项目上下文,对话式生成 | 需付费,依赖外部LLM API |
| Claude Code | ⭐⭐⭐⭐ | Agent模式可自动运行测试并修复错误 | 命令行工具,学习曲线较高 |
| 通义灵码 | ⭐⭐⭐⭐ | 阿里出品,中文理解好,免费,支持企业内部部署 | 国际框架支持略弱于GitHub Copilot |
| 文心快码 | ⭐⭐⭐ | 百度出品,对Java/Spring生态友好 | 框架覆盖范围有限 |
| ChatGPT (Web) | ⭐⭐⭐ | 零门槛,适合快速原型和验证 | 无IDE集成,需手工粘贴,缺乏项目上下文 |
| Amazon CodeWhisperer | ⭐⭐⭐ | AWS生态集成好,安全性扫描 | 测试框架支持有限 |
6.2 提示词模板
高质量的Prompt是获得高质量脚本的前提。以下提供几个可直接使用的提示词模板:
模板一:通用UI测试脚本生成
你是一个资深自动化测试工程师。请根据以下测试场景生成 {框架名} 测试脚本。
【测试框架】Playwright + TypeScript
【测试场景】
- 页面URL:{页面地址}
- 前置条件:{前置条件描述}
- 测试步骤:
1. {步骤1}
2. {步骤2}
...
- 预期结果:{预期结果描述}
【代码规范要求】
- 使用 Page Object 模式
- 优先使用 data-testid 定位元素
- 使用智能等待,避免硬编码 sleep
- 断言需覆盖关键业务验证点
- 添加清晰的注释
模板二:API测试脚本生成
你是一个后端测试专家。请根据以下API定义生成pytest测试脚本。
【API信息】
- 方法:{GET/POST/PUT/DELETE}
- 路径:{/api/v1/xxx}
- 请求参数:{参数说明}
- 响应格式:{JSON结构}
【测试覆盖要求】
- 正常请求(200/201)
- 参数校验(400)
- 认证失败(401)
- 权限不足(403)
- 资源不存在(404)
- 边界值测试
【输出格式】可独立运行的pytest文件,包含必要的fixture和参数化装饰器。
模板三:脚本优化重构
请优化以下测试脚本,提升可维护性和健壮性:
【优化要求】
1. 将脆弱的XPath定位器改为 data-testid 或语义化定位
2. 将硬编码sleep替换为智能等待
3. 提取Page Object模式
4. 补充缺失的断言
5. 添加teardown清理逻辑
【原始脚本】
{粘贴原始脚本}
模板四:跨框架转换
请将以下 {源框架} 测试脚本转换为 {目标框架} 的等效脚本。
【转换要求】
- 保持原有测试逻辑和断言不变
- 适配目标框架的API和最佳实践
- 处理异步/同步差异
- 保持代码风格一致
【源脚本】
{粘贴源脚本}
- 越具体越好——提供元素定位信息、预期行为描述
- 提供正例——附上1-2个团队中已通过审查的脚本样例
- 分步骤生成——复杂场景先让AI生成大纲,确认后再生成完整代码
- 善用迭代——第一版不满意时,在对话中指出问题并要求修正
7. 实战演练
以下实战任务涵盖了脚本智能生成的三个核心场景,从基础的自然语言生成到进阶的银行接口测试。建议逐项练习,完成后对照评估标准进行复盘。
🔰 任务一:从自然语言生成测试脚本
| 任务概览 | |
|---|---|
| 场景 | 为某电商平台的用户登录功能编写 Playwright 自动化测试脚本。利用 LLM 将自然语言描述的测试步骤转换为可执行脚本。 |
| 背景 | 团队正在搭建 Playwright 自动化测试框架,部分测试人员具备业务知识但不熟悉 Playwright API,需要借助 AI 快速上手。目标页面为 https://shop.example.com/login,包含用户名输入框(id=username)、密码输入框(id=password)、登录按钮(id=login-btn)。 |
操作步骤
- 编写自然语言描述:用中文详细描述登录测试场景,包括前置条件、每个操作步骤、预期结果。描述越精确,生成质量越高。
- 选择 Prompt 模板:使用本章第 6.2 节的「模板一:通用UI测试脚本生成」,指定框架为 Playwright + TypeScript。
- 提交 LLM 生成:将组装好的 Prompt 提交给 LLM(推荐 Claude、GPT-4 或 Cursor),获取生成的测试脚本。
- 审查生成脚本:对照第 4.4 节的审查清单,逐项检查:脚本能否运行、断言是否有效、定位策略是否稳健、是否有硬编码等待。
- 本地运行验证:在本地 Playwright 环境中执行脚本,观察运行结果,记录并修复发现的问题。
参考输入示例
测试场景:用户登录功能验证
前提条件:用户已在登录页面(https://shop.example.com/login)
测试步骤:
1. 在用户名输入框(id=username)中输入 "testuser@shop.com"
2. 在密码输入框(id=password)中输入 "Test@123456"
3. 点击"登录"按钮(id=login-btn)
4. 验证页面跳转到 /dashboard
5. 验证页面包含文字 "欢迎回来,testuser"
6. 验证导航栏显示用户头像(class=user-avatar)
评估标准
| 维度 | 标准 | 权重 |
|---|---|---|
| 可运行性 | 脚本复制到项目中可直接执行,无需手动修复语法/API错误 | ⭐⭐⭐⭐⭐ |
| 断言覆盖 | 覆盖了 URL 跳转、页面文案、元素可见性三个维度的验证 | ⭐⭐⭐⭐ |
| 定位策略 | 优先使用 id 定位,未使用脆弱的选择器(如绝对 XPath) | ⭐⭐⭐⭐ |
| 等待策略 | 使用 Playwright 自动等待机制,无硬编码 sleep | ⭐⭐⭐ |
| 代码规范 | 命名清晰、注释完整、符合 Playwright 推荐风格 | ⭐⭐⭐ |
⏱ 预计耗时:30 分钟
🔄 任务二:脚本跨框架转换
| 任务概览 | |
|---|---|
| 场景 | 将一段 Selenium Java 测试脚本转换为 Playwright Python 等效脚本。保留原有测试逻辑和断言,适配目标框架的 API 和最佳实践。 |
| 背景 | 团队决定将 UI 自动化测试框架从 Selenium Java 迁移到 Playwright Python,有 200+ 个存量脚本需要转换。手动逐条重写效率低且容易引入回归问题,计划使用 AI 辅助批量转换。本任务选取一个典型的搜索功能测试脚本作为转换试点,验证转换质量和效率。 |
操作步骤
- 选取源脚本:使用下方提供的 Selenium Java 脚本(商品搜索功能测试),阅读并理解其测试逻辑。
- 组装 Prompt:使用本章第 6.2 节的「模板四:跨框架转换」,将源脚本填入,指定目标框架为 Playwright + Python + pytest。
- 提交 LLM 转换:将 Prompt 提交给 LLM,观察其如何处理 Java→Python 语法转换和 Selenium→Playwright API 映射。
- 人工审查:重点检查:(1) 测试逻辑是否完整保留;(2) 异步等待是否正确处理;(3) Playwright API 使用是否地道;(4) 是否存在幻觉 API。
- 运行对比:在本地 Playwright 环境中运行转换后的脚本,对照原 Selenium 脚本的行为,确认功能一致。
源脚本(Selenium Java)
import org.junit.jupiter.api.*;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import java.time.Duration;
import static org.junit.jupiter.api.Assertions.*;
public class ProductSearchTest {
WebDriver driver;
WebDriverWait wait;
@BeforeEach
void setUp() {
driver = new ChromeDriver();
wait = new WebDriverWait(driver, Duration.ofSeconds(10));
driver.get("https://shop.example.com");
}
@Test
void testSearchProduct() {
// 输入搜索关键词
WebElement searchBox = wait.until(
ExpectedConditions.visibilityOfElementLocated(By.id("search-input"))
);
searchBox.sendKeys("无线耳机");
// 点击搜索按钮
driver.findElement(By.id("search-btn")).click();
// 等待搜索结果加载
wait.until(ExpectedConditions.visibilityOfElementLocated(
By.cssSelector(".product-list")
));
// 验证搜索结果不为空
int resultCount = driver.findElements(By.cssSelector(".product-item")).size();
assertTrue(resultCount > 0, "搜索结果不应为空");
// 验证每个结果包含关键词
for (WebElement item : driver.findElements(By.cssSelector(".product-item .product-name"))) {
String title = item.getText().toLowerCase();
assertTrue(title.contains("耳机"),
"商品标题应包含搜索关键词");
}
}
@AfterEach
void tearDown() {
if (driver != null) {
driver.quit();
}
}
}
评估标准
| 维度 | 标准 | 权重 |
|---|---|---|
| 逻辑完整性 | 所有测试步骤、断言条件完整保留,无遗漏或篡改 | ⭐⭐⭐⭐⭐ |
| API 映射准确性 | Selenium API 正确映射到 Playwright 等效 API(如 findElement → locator,显式等待 → 自动等待) | ⭐⭐⭐⭐⭐ |
| 异步处理 | 正确使用 async/await(若转 TS)或 Playwright sync API(若转 Python),无阻塞调用遗留 | ⭐⭐⭐⭐ |
| 代码风格 | 符合目标框架的命名规范和代码风格(如 pytest 的 test_ 前缀、snake_case 命名) | ⭐⭐⭐ |
| 可运行性 | 转换后的脚本在目标环境中可直接运行通过 | ⭐⭐⭐ |
⏱ 预计耗时:45 分钟
🏦 任务三:银行转账接口测试脚本生成
| 任务概览 | |
|---|---|
| 场景 | 根据银行转账 API 的 OpenAPI 3.0 规范,利用 LLM 自动生成覆盖正常和异常场景的接口测试脚本(pytest + requests)。 |
| 背景 | 某银行新上线了行内转账接口,提供了 OpenAPI 3.0 规范文档。接口涉及金额校验、账户状态检查、交易签名等银行特有逻辑。测试团队需要在 2 天内完成接口测试脚本开发,覆盖状态码 200/400/401/403/500 以及边界值场景。手动编写耗时长,且容易遗漏异常分支。 |
操作步骤
- 分析 API 定义:阅读下方提供的 OpenAPI 片段,识别 endpoint、请求参数、响应 schema、必填/选填字段、参数约束(格式、范围)。
- 确定测试覆盖范围:设计测试矩阵——正常转账、余额不足、账户不存在、金额超限、未授权访问、必填字段缺失、并发重复提交。
- 组装 Prompt:使用本章第 6.2 节的「模板二:API测试脚本生成」,将 OpenAPI 片段、测试覆盖要求、银行特有约束(如签名验签)一并提交。
- 审查生成脚本:重点检查:(1) 状态码断言覆盖是否完整;(2) 签名/鉴权逻辑是否正确;(3) 异常场景的错误码验证是否到位。
- 补充安全验证:银行接口需额外验证:幂等性(重复提交不重复扣款)、交易金额精度、敏感信息脱敏。手动补充相关断言。
API 定义(OpenAPI 3.0 片段)
openapi: "3.0.0"
info:
title: 银行行内转账 API
version: "1.0.0"
paths:
/api/v1/transfer/internal:
post:
summary: 行内转账
security:
- BearerAuth: []
- X-Signature: []
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [fromAccount, toAccount, amount, currency]
properties:
fromAccount:
type: string
pattern: '^\d{19}$'
description: 转出账号(19位)
toAccount:
type: string
pattern: '^\d{19}$'
description: 转入账号(19位)
amount:
type: number
minimum: 0.01
maximum: 500000.00
description: 转账金额(元)
currency:
type: string
enum: [CNY]
description: 币种
memo:
type: string
maxLength: 50
description: 附言(选填)
responses:
'200':
description: 转账成功
content:
application/json:
schema:
type: object
properties:
transactionId:
type: string
pattern: '^TXN\d{16}$'
status:
type: string
enum: [SUCCESS]
timestamp:
type: string
format: date-time
'400':
description: 请求参数错误
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'401':
description: 认证失败
'403':
description: 权限不足
'409':
description: 余额不足或账户状态异常
'429':
description: 请求过于频繁
'500':
description: 服务器内部错误
components:
securitySchemes:
BearerAuth:
type: http
scheme: bearer
X-Signature:
type: apiKey
in: header
name: X-Signature
description: 请求体 HMAC-SHA256 签名
schemas:
ErrorResponse:
type: object
properties:
code:
type: string
message:
type: string
requestId:
type: string
评估标准
| 维度 | 标准 | 权重 |
|---|---|---|
| 状态码覆盖 | 至少覆盖 200、400、401、403、409、500 六种响应场景,每种有独立的测试用例 | ⭐⭐⭐⭐⭐ |
| 参数校验 | 覆盖必填字段缺失、账号格式错误、金额超限/为零/为负、币种非法值等边界场景 | ⭐⭐⭐⭐⭐ |
| 安全验证 | 包含签名生成逻辑(HMAC-SHA256),验证鉴权头正确传递;包含幂等性测试 | ⭐⭐⭐⭐ |
| 数据管理 | 使用 fixture 管理测试账号和金额,teardown 中清理测试数据;敏感信息不硬编码 | ⭐⭐⭐⭐ |
| 可维护性 | Base URL、超时、重试策略集中配置;参数化装饰器合理使用;断言信息清晰可读 | ⭐⭐⭐ |
⏱ 预计耗时:60 分钟
📋 案例研究:AI辅助转账接口测试脚本生成
📖 背景
某金融科技公司的测试团队面临大量重复性接口测试任务,决定尝试使用大语言模型(LLM)为银行转账接口自动生成 Playwright 自动化测试脚本,以提升测试效率。
🔄 过程
测试人员将转账接口的需求文档和 API 规范以自然语言描述输入给 LLM,由模型自动生成测试脚本框架 → 资深测试工程师对生成的脚本进行人工审查,标注问题和改进点 → 在测试环境中运行脚本,记录首次执行结果 → 根据失败用例和审查意见,对脚本进行人工修复和优化。整个流程形成「自然语言描述 → LLM生成 → 人工审查 → 运行调试 → 优化迭代」的闭环。
📊 结果
- 共生成 50 条自动化测试脚本,覆盖正常流程、异常处理、边界值和安全鉴权四大场景
- 首次执行通过率为 60%(30/50),主要失败原因集中在断言不精确和边界值处理不当
- 经过两轮人工修复后,最终通过率达到 95%(48/50),剩余 2 条涉及复杂业务规则的场景仍需人工维护
💡 启示
- 框架生成效率高:AI 在生成测试脚本骨架、基础请求构造和公共方法封装方面表现优异,可节省约 70% 的初期编写时间
- 断言需人工补充:LLM 对业务语义理解有限,生成的断言往往过于简单或偏离业务预期,需要测试人员根据实际业务逻辑进行精细化调整
- 边界值覆盖不足:AI 生成的脚本对边界值(如金额为 0、超大数值、特殊字符等)的覆盖不够全面,需人工补充边界测试用例
- 最佳实践:建议采用「AI 生成 + 人工审查」的协作模式,AI 负责框架搭建和基础用例生成,人工聚焦于断言优化、边界补充和业务逻辑验证