【Hermes系列8】Hermes 生成的测试代码能直接用吗?我 Review 了 10 个脚本(附真实评测数据)
Hermes 生成的代码,我打了 71 分(附 Review 清单)| AI 测试代码质量评估:20% 可直接用,40% 需修改,40% 要重写
这是 Hermes 系列的第 8 篇,也是深度分析篇。
前 7 篇我们解决了:是什么、怎么用、实战场景、CI 集成。但还有一个灵魂问题:
Hermes 生成的测试代码,质量到底怎么样?能直接用吗?需要人工 Review 吗?
作为一个测试老兵,我搭建了一个真实的电商演示系统,让 Hermes 生成了 10 个测试脚本,用专业测试的视角逐一评审。
今天这篇,我把评估结果完整分享给你。
包括:
- 评估维度(5 个核心指标)
- 评分结果(平均分 70.9/100)
- 典型问题(4 大类 90 个小项)
- 改进建议(如何让 Hermes 生成更好的代码)
- Review Checklist(可直接用)
- 真实评测数据(源码开源)
我承诺一个结果:你照着本文的 Checklist 走,10 分钟内能评估任何 Hermes 生成的测试代码。
02
评估背景
为什么做这个评估?
Hermes 系列发布后,后台收到最多的问题是:
"周周,Hermes 生成的代码我不敢直接用,怎么判断质量?"
"AI 写的测试脚本,需要人工 Review 吗?Review 什么?"
"有没有一个清单,能帮我快速评估代码质量?"
作为测试我深知:代码质量决定维护成本。
一个写得不好的测试脚本,短期能跑,长期是债。
所以我做了这个评估——给 Hermes 生成的代码一次系统性体检。
10 个脚本的来源:
| 来源 | 数量 | 说明 |
|---|---|---|
| 本次实测生成 | 10 个 | 针对演示电商系统生成 |
| 测试场景覆盖 | 10 个 | 登录 (3)、仪表盘 (1)、商品 (3)、订单 (2)、退出 (1) |
演示系统:Flask 电商系统(用户登录、商品管理、订单管理)
评估时间:2026-04-15(实测)
评估方法:
- 静态代码分析(不运行,看代码)
- 动态执行验证(运行,看结果)
- 自动化评审脚本(Python + Review Checklist)
03
评估维度
我定义了 5 个核心维度,每个维度 20 分,总分 100 分:
| 维度 | 权重 | 评估内容 |
|---|---|---|
| 代码可读性 | 20% | 命名、注释、结构、一致性 |
| 定位器稳定性 | 30% | ID 优先、XPath 慎用、等待策略 |
| 断言覆盖率 | 25% | 关键检查点、边界验证、错误处理 |
| 异常处理 | 15% | 超时、重试、截图、日志 |
| 可维护性 | 10% | 模块化、可复用、配置分离 |
为什么这样权重?
定位器稳定性 (30%) + 断言覆盖率 (25%) = 55%
这是测试脚本的核心价值:
- 定位器不稳 → 脚本 flaky(时过不过)
- 断言不全 → 测了等于没测
可读性和异常处理可以后期优化,但核心质量必须一开始就过关。
04
评估结果
总体评分:
| 指标 | 数值 |
|---|---|
| 平均分 | 70.9/100 |
| 最高分 | 87/100 |
| 最低分 | 50/100 |
| 中位数 | 71/100 |
分级统计:
| 等级 | 分数范围 | 数量 | 占比 | 说明 |
|---|---|---|---|---|
| A(可直接用) | 85-100 | 2 个 | 20% | 无需修改或仅需微调 |
| B(需小幅修改) | 70-84 | 4 个 | 40% | 修改后可用 |
| C(需大幅重写) | 50-69 | 4 个 | 40% | 核心逻辑需重写 |
| D(不可用) | <50 | 0 个 | 0% | 无 |
结论:
- 20% 可直接用 → Hermes 能胜任简单场景
- 40% 需小幅修改 → 主流情况,人工 Review 有价值
- 40% 需大幅重写 → 复杂场景仍需测试专家介入
Hermes 的定位:快速生成初版,减少重复劳动
不是:完全替代人工测试工程师
📊 评测详情:
| 脚本 | 得分 | 等级 | 问题数 |
|---|---|---|---|
| 04-test_dashboard_load.py | 87 | A | 5 |
| 08-test_create_order.py | 85 | A | 6 |
| 01-test_login_success.py | 75 | B | 8 |
| 06-test_add_product.py | 75 | B | 8 |
| 09-test_create_order_insufficient_stock.py | 72 | B | 9 |
| 10-test_logout.py | 70 | B | 9 |
| 02-test_login_wrong_password.py | 65 | C | 11 |
| 03-test_login_empty_username.py | 65 | C | 11 |
| 05-test_products_page_load.py | 65 | C | 11 |
| 07-test_delete_product.py | 50 | C | 12 |
05
各维度得分详情
维度 1:代码可读性(平均分 76/100)
| 子项 | 平均分 | 典型问题 |
|---|---|---|
| 变量命名 | 80/100 | 部分用 a/b/c 等无意义命名 |
| 函数注释 | 75/100 | 有注释但不够详细 |
| 代码结构 | 78/100 | 大部分结构清晰 |
| 一致性 | 72/100 | 命名风格不统一(camelCase vs snake_case) |
好例子:
# ✅ 好的命名
def login_with_valid_credentials():
"""使用有效凭据登录系统"""
username = "admin"
password = "123456"
login_page.enter_username(username)
login_page.enter_password(password)
login_page.click_login_button()
坏例子:
# ❌ 坏的命名
def test1():
a = "admin"
b = "123456"
page.fill("#username", a)
page.fill("#password", b)
page.click("#login-btn")
维度 2:定位器稳定性(平均分 68/100)⭐ 最弱项
| 子项 | 平均分 | 典型问题 |
|---|---|---|
| ID 优先 | 75/100 | 部分未用 ID |
| XPath 慎用 | 55/100 | XPath 使用过多 |
| 等待策略 | 65/100 | 缺少显式等待 |
| 选择器可读性 | 78/100 | 大部分选择器可读性好 |
典型问题:
# ❌ 问题 1:XPath 写死(页面一变就挂)
page.click("/html/body/div[1]/div[2]/div[3]/button[2]")
# ✅ 改进:用 ID 或 role
page.click("#submit-btn")
page.get_by_role("button", name="提交").click()
# ❌ 问题 2:缺少等待(竞态条件)
page.click("#login-btn")
assert page.url == "/home" # 可能页面还没跳转
# ✅ 改进:显式等待
page.click("#login-btn")
page.wait_for_url("/home", timeout=5000)
assert page.url == "/home"
# ❌问题 3:CSS 选择器过于复杂
page.click(".container > div:nth-child(3) > form > input:nth-child(2)")
# ✅ 改进:简化选择器
page.click("#username")
维度 3:断言覆盖率(平均分 71/100)
| 子项 | 平均分 | 典型问题 |
|---|---|---|
| 关键检查点 | 75/100 | 部分缺少关键断言 |
| 边界验证 | 60/100 | 边界场景覆盖不足 |
| 错误消息验证 | 68/100 | 错误消息未验证 |
| 状态验证 | 78/100 | 大部分有状态验证 |
典型问题:
# ❌ 问题 1:只验证成功,不验证失败
def test_login():
page.fill("#username", "admin")
page.fill("#password", "123456")
page.click("#login-btn")
assert page.url == "/home" # 只验证成功场景
# ✅ 改进:覆盖失败场景
def test_login_success():
# 成功场景
...
def test_login_wrong_password():
# 失败场景:密码错误
page.fill("#username", "admin")
page.fill("#password", "wrong")
page.click("#login-btn")
assert "密码错误" in page.text_content(".error-message")
# ❌ 问题 2:断言太弱
assert page.url # 只检查 URL,没检查内容
# ✅ 改进:多重断言
assert page.url == "/home"
assert "欢迎" in page.text_content("h1")
assert user_info.is_visible()
维度 4:异常处理(平均分 74/100)
| 子项 | 平均分 | 典型问题 |
|---|---|---|
| 超时处理 | 70/100 | 部分缺少超时设置 |
| 重试机制 | 65/100 | 重试逻辑不足 |
| 截图保存 | 80/100 | 大部分有截图 |
| 日志记录 | 75/100 | 日志详细度中等 |
典型问题:
# ❌ 问题 1:没有超时设置
page.click("#submit-btn") # 如果按钮加载慢,可能卡死
# ✅ 改进:设置超时
page.click("#submit-btn", timeout=10000)
# ❌ 问题 2:失败时没有截图
try:
assert page.url == "/home"
except AssertionError:
pass # 失败时什么都不做
# ✅ 改进:失败时截图
try:
assert page.url == "/home"
except AssertionError:
page.screenshot(path="screenshots/login_failed.png")
raise
维度 5:可维护性(平均分 78/100)
| 子项 | 平均分 | 典型问题 |
|---|---|---|
| 模块化 | 75/100 | 部分代码未拆分函数 |
| 可复用性 | 72/100 | 重复代码较多 |
| 配置分离 | 85/100 | 大部分配置已分离 |
| 数据驱动 | 70/100 | 测试数据硬编码较多 |
典型问题:
# ❌ 问题 1:测试数据硬编码
def test_login():
page.fill("#username", "admin")
page.fill("#password", "123456")
# ✅ 改进:配置分离
TEST_ACCOUNTS = {
"admin": {"username": "admin", "password": "***"},
"user": {"username": "testuser", "password": "***"}
}
def test_login(account_type="admin"):
account = TEST_ACCOUNTS[account_type]
page.fill("#username", account["username"])
page.fill("#password", account["password"])
# ❌ 问题 2:重复代码
def test_login_success():
page.goto("http://localhost:5000/login")
page.fill("#username", "admin")
page.fill("#password", "123456")
page.click("#login-btn")
def test_login_wrong_password():
page.goto("http://localhost:5000/login")
page.fill("#username", "admin")
page.fill("#password", "wrong")
page.click("#login-btn")
# ✅ 改进:抽取公共方法
def navigate_to_login():
page.goto("http://localhost:5000/login")
def login(username, password):
page.fill("#username", username)
page.fill("#password", password)
page.click("#login-btn")
06
问题分类统计
问题分布:
| 类别 | 问题数 | 占比 | 典型问题 |
|---|---|---|---|
| 代码结构 | 55 | 61% | 缺少文档字符串、URL 硬编码、测试数据硬编码 |
| 异常处理 | 28 | 31% | 缺少超时设置、没有异常捕获、失败时没有截图 |
| 断言问题 | 6 | 7% | 只有一个断言、缺少 URL 验证 |
| 定位器问题 | 1 | 1% | 使用硬编码索引 (nth-child) |
💡 关键发现:
1. 代码结构问题最多(61%)→ 主要是缺少文档和配置分离
2. 异常处理普遍不足(31%)→ AI 倾向于生成"快乐路径"代码
3. 定位器问题较少(1%)→ Hermes 默认使用 ID 选择器,表现良好
07
关键发现与洞察
基于本次评测的 10 个脚本和 90 个问题项,我有 3 个核心洞察:
洞察 1:Hermes 擅长"形",不擅长"神"
TEXT
"形" → 代码结构、选择器使用、基本流程(得分 80+)
"神" → 异常处理、边界思考、质量意识(得分 30-40)
这很合理。AI 学习的是代码的"表象",但测试的"灵魂"是质疑和防御思维。
洞察 2:AI 生成的代码,像初级测试工程师写的
共同特点:
- 能跑通"快乐路径"(Happy Path)
- 缺少异常场景思考
- 不会主动加文档和注释
- 需要 Code Review 指导
这不是问题,而是定位。Hermes 的价值是帮你快速生成初版,然后你来当 Reviewer。
洞察 3:Prompt 质量决定代码质量的上限
同样的登录场景,我做了对比实验:
| Prompt | 得分 | 差异 |
|---|---|---|
| "写一个登录测试" | 65 分 | 基础版本 |
| "写一个登录测试,要求添加异常处理和截图" | 78 分 | +13 分 |
| 详细需求 + 示例代码 | 85 分 | +20 分 |
你给 Hermes 的上下文越详细,它生成的代码越接近你的期望。
08
下篇预告
这篇文章只讲了"评测结果",但更重要的是"如何改进"。
下篇《Hermes 生成代码质量提升指南:从 70 分到 90 分的 5 个技巧》我会讲:
✅ 改进实战 1:如何补充异常处理(50 分 → 85 分)
✅ 改进实战 2:如何优化等待策略(消除固定等待)
✅ 改进实战 3:如何强化断言(从 1 个到 5 个)
✅ Prompt 技巧:4 个让 Hermes 生成更好代码的方法
✅ 迭代优化:如何让 Hermes 逐步改进代码
✅ Review 工具:自动化评审脚本使用说明
预计发布时间:明天(关注公众号,不错过更新)
源码获取:私信
09
结论与建议
Hermes 的定位:
✅ 适合:
- 快速生成测试脚本初版
- 减少重复劳动(如 CRUD 测试)
- 标准化场景(登录、查询、列表)
- 测试数据准备
❌ 不适合:
- 完全替代人工测试工程师
- 复杂业务逻辑测试
- 高可靠性要求的场景(如金融、医疗)
- 需要深度领域知识的场景
我的建议:
1. 用 Hermes 生成初版(节省 70% 时间)
2. 人工 Review 和优化(花 30% 时间保证质量)
3. 建立团队规范(Review Checklist)
4. 持续迭代(根据反馈优化提示词)
ROI 计算:
传统方式:
- 写一个测试脚本:30 分钟
- 10 个脚本:300 分钟(5 小时)
Hermes + Review:
- 生成初版:5 分钟
- Review + 优化:10 分钟
- 10 个脚本:150 分钟(2.5 小时)
效率提升:50%
质量:可控(有 Review)
11
谢谢你看到这里。
这篇可能是系列里最硬核的一篇——用 10 个脚本换你一个清晰的判断框架。
Hermes 生成的代码,71 分,及格以上,优秀未满。
但这正是 AI 工具的正确打开方式:
AI 生成初版(70 分)+ 人工 Review 优化(+20 分)= 90 分高质量代码
不是让 AI 替代你
而是让 AI 放大你的价值
留言告诉我:
- 你用 Hermes 生成过代码吗?质量如何?
- 你最关心代码的哪个方面?
- 你有自己的 Review 清单吗?
每一条留言,我都会看,都会回。
AI 生成的代码,71 分;人工 Review 的价值,29 分;合起来才是 100 分。
P.S. 如果你不想错过更新,记得点个在看或者分享到朋友圈。
P.P.S. Hermes 系列共 15 篇,这是第 8 篇。建议收藏,方便后续查阅。
(全文约 6500 字,阅读时间约 18 分钟)
动手试试
读完这篇文章,你可以:
- 用 Review Checklist 评估你生成的测试代码
- 根据问题项,让 Hermes 迭代优化
- 下载源码,复现本次评测
- 在留言区分享:你给 Hermes 代码打几分?
别等完美,先跑起来。迭代,是通往优秀的唯一路径。
作者:测试员周周,14 年测试经验,专注 AI+ 测试实战