【Hermes系列4】测试实战-商品后台最怕「组合爆炸」:我用 Hermes 压住新增+查询,先出表再落脚本(实战④)

0 阅读22分钟

01

大家好,我是测试员周周,全网同名。这是 Hermes 系列第 4 篇,也是商品管理模块的测试实战篇。

上一篇我们把登录回归跑通了一条闭环。这篇做天然更“碎”的事:新增 + 查询——字段多、边界多、组合多,最适合验证 Hermes 能不能把表格式思维一次拉齐。

如果你也遇到过这些场景,这篇就是给你写的: - 每次发版都要手动测商品后台,重复劳动 - 新增场景多(必填、选填、价格/库存边界) - 查询要考虑多种条件组合,脑子能想到,手抄用例抄不完 - 测试数据准备烦:录几条假数据就要半下午

我承诺一个结果:你不需要先会写 Page Object,只要会给 URL、账号、字段大致长什么样,Hermes 能帮你把用例表和脚本骨架先顶上——你再做人审与微调。


02

再补一层背景,和第 3 篇「登录」是同一套世界观。

很多团队第一步会想上测试平台:用例库、执行记录、报表——没问题,但前后端 + 权限 + 运营一上来就是小产品量级,离不开持续投入。

另一条路是 Skills / 插件化:轻一些,但你照样要维护「机器可读」的制品,改一版页面可能要改一版技能说明。

Hermes 这条路径里,我更常做的是:把商品管理页直接交给它(链接、截图、关键字段名),让它先读结构、列风险、吐用例草案,再决定是否落 Playwright。配置齐的话,不必先写一堆独立 Skills 文件,对话就能走完大半;要固化了,再抽到团队模板库。

底线不变:内网隔离、合规要求时,生成脚本在你本地跑;财务级精度的断言,仍建议人工点名 P0 文案,而不是全信第一版模型输出。


03

本篇交付:商品管理里的 新增商品 + 查询商品,共 11 条用例思路 + 一份可运行的 Python + Playwright 示例骨架(含 Page Object)。

你会带走: - 比登录多一倍的「组合爆炸」怎么拆成可执行表 - 同一套提示词模板,换模块仍能复用 - 知道数据怎么造列表断言怎么收敛才不 brittle


04

系统背景

我们要测试的是一个电商秒杀与财务一体化系统的商品管理模块。

系统信息: - 系统 URL:http://localhost:5000 - 登录账号:admin / 123456 - 商品管理页面:http://localhost:5000/products#manage

测试目标

本次实战聚焦商品管理的两个核心功能:

功能 1:新增商品
测试项测试内容预期结果
正常新增填写所有必填项(商品名称、价格、库存)添加成功,列表显示新商品
商品名称为空不输入商品名称,其他必填提示"请输入商品名称"
价格为负数价格输入 -100提示"价格必须大于 0"
价格为 0价格输入 0提示"价格必须大于 0"
库存为负数库存输入 -50提示"库存必须大于等于 0"
价格超过最大值价格输入 999999999提示"价格超出范围"或自动格式化
功能 2:查询商品
测试项测试内容预期结果
按名称查询输入商品名称关键词显示匹配的商品列表
按价格范围查询输入最低价格和最高价格显示价格范围内的商品
组合查询名称 + 价格范围同时输入显示同时满足条件的商品
查询无结果输入不存在的商品名称显示"暂无数据"或空列表
重置查询点击重置按钮清空搜索条件,显示全部商品

测试环境

项目配置
系统 URLhttp://localhost:5000
登录账号admin / 123456
浏览器Chrome / Firefox
测试工具Hermes Agent + Playwright

05

登录之后的模块测试,字段越多,越适合先让 Hermes「看页面再写表」;下面仍保留带完整元素 ID 的「明细版」,方便你一键对齐后文长脚本。

更轻的一版起手式(可选)

先把商品管理页丢给 Hermes,让它自己长眼睛,再进入正文里那大段「元素 ID 清单」也可以:

bash📋 复制

请打开(或根据截图分析)电商后台的商品管理页,识别新增商品所需的表单字段、查询区的输入项与按钮。在已知登录账号 admin/123456、系统 http://localhost:5000 的前提下,列出「新增商品」与「查询商品」的 P0/P1 用例草案(表格列:名称、数据、预期),暂不写代码。

它若已能访问页面,通常会顺便给出更稳的定位策略(id / placeholder / role);你再把结论粘贴回「明细版」提示词里,后文示例不易跑偏。


第一步:告诉 Hermes 要做什么

打开你与 Hermes 的对话(飞书机器人或 CLI),输入以下提示词:

bash📋 复制

我要对电商后台管理系统的商品管理模块进行测试。系统信息:- 登录页面:http://localhost:5000/login- 商品管理页面:http://localhost:5000/products#manage- 测试账号:用户名 admin,密码 123456- 新增商品表单元素:  - 商品名称输入框 ID:product-name  - 价格输入框 ID:product-price  - 库存输入框 ID:product-stock  - 添加按钮 ID:add-btn  - 成功提示元素 class:success-message- 查询功能元素:  - 搜索框 ID:search-input  - 最低价格 ID:min-price  - 最高价格 ID:max-price  - 查询按钮 ID:search-btn  - 重置按钮 ID:reset-btn  - 商品列表表格 ID:product-table请帮我:1. 拆解新增商品和查询商品的测试任务为可执行的步骤2. 生成测试用例表格(新增商品 6 个用例,查询商品 5 个用例)3. 输出结构化的测试用例表格

Hermes 返回的任务拆解

Hermes 会返回类似下面的内容:

bash📋 复制

【任务理解】你需要对电商后台商品管理模块的两个功能进行测试:1. 新增商品功能(6 个测试场景)2. 查询商品功能(5 个测试场景)【测试步骤拆解】步骤 1:登录系统- 打开登录页面- 输入用户名 admin- 输入密码 123456- 点击登录- 验证是否跳转到后台首页步骤 2:进入商品管理页面- 点击商品管理菜单- 验证是否进入 /products#manage 页面步骤 3:执行新增商品测试用例- 用例 1:正常新增商品- 用例 2:商品名称为空- 用例 3:价格为负数- 用例 4:价格为 0- 用例 5:库存为负数- 用例 6:价格超过最大值步骤 4:执行查询商品测试用例- 用例 1:按名称查询- 用例 2:按价格范围查询- 用例 3:组合查询- 用例 4:查询无结果- 用例 5:重置查询步骤 5:记录结果并生成报告- 每个用例的执行结果(通过/失败)- 实际响应与预期对比- 截图保存(失败用例)- 生成结构化测试报告

第二步:让 Hermes 生成测试用例

继续输入:

bash📋 复制

请把上面的测试步骤转换成可执行的测试用例表格,包含以下列:- 用例编号(TC001-TC011)- 功能模块(新增商品/查询商品)- 用例名称- 前置条件- 测试步骤- 测试数据- 预期结果- 优先级(P0/P1)

Hermes 会返回:

bash📋 复制

【商品管理功能测试用例】| 编号 | 功能模块 | 名称 | 前置条件 | 测试步骤 | 测试数据 | 预期结果 | 优先级 ||------|----------|------|----------|----------|----------|----------|--------|| TC001 | 新增商品 | 正常新增商品 | 已登录 | 1.点击添加商品 2.输入商品名称 3.输入价格 4.输入库存 5.点击添加 | 名称:测试商品 001 价格:99.9 库存:100 | 添加成功,列表显示新商品,提示"添加成功" | P0 || TC002 | 新增商品 | 商品名称为空 | 已登录 | 1.点击添加商品 2.不输入名称 3.输入价格 4.输入库存 5.点击添加 | 名称:(空) 价格:99.9 库存:100 | 提示"请输入商品名称",添加失败 | P0 || TC003 | 新增商品 | 价格为负数 | 已登录 | 1.点击添加商品 2.输入名称 3.输入负数价格 4.输入库存 5.点击添加 | 名称:测试商品 002 价格:-100 库存:100 | 提示"价格必须大于 0",添加失败 | P0 || TC004 | 新增商品 | 价格为 0 | 已登录 | 1.点击添加商品 2.输入名称 3.输入价格 0 4.输入库存 5.点击添加 | 名称:测试商品 003 价格:0 库存:100 | 提示"价格必须大于 0",添加失败 | P1 || TC005 | 新增商品 | 库存为负数 | 已登录 | 1.点击添加商品 2.输入名称 3.输入价格 4.输入负数库存 5.点击添加 | 名称:测试商品 004 价格:99.9 库存:-50 | 提示"库存必须大于等于 0",添加失败 | P0 || TC006 | 新增商品 | 价格超过最大值 | 已登录 | 1.点击添加商品 2.输入名称 3.输入超大价格 4.输入库存 5.点击添加 | 名称:测试商品 005 价格:999999999 库存:100 | 提示"价格超出范围"或自动格式化 | P1 || TC007 | 查询商品 | 按名称查询 | 已登录,列表有数据 | 1.在搜索框输入关键词 2.点击查询 | 关键词:测试 | 显示名称包含"测试"的商品 | P0 || TC008 | 查询商品 | 按价格范围查询 | 已登录,列表有数据 | 1.输入最低价格 2.输入最高价格 3.点击查询 | 最低价:50 最高价:150 | 显示价格在 50-150 之间的商品 | P1 || TC009 | 查询商品 | 组合查询 | 已登录,列表有数据 | 1.输入关键词 2.输入价格范围 3.点击查询 | 关键词:测试 最低价:50 最高价:150 | 显示同时满足条件的商品 | P1 || TC010 | 查询商品 | 查询无结果 | 已登录 | 1.输入不存在的商品名称 2.点击查询 | 关键词:不存在的商品 XYZ | 显示"暂无数据"或空列表 | P1 || TC011 | 查询商品 | 重置查询 | 已登录,已输入查询条件 | 1.输入查询条件 2.点击重置 | 任意条件 | 清空所有查询条件,显示全部商品 | P1 |

06

第三步:生成 Playwright 自动化脚本

输入提示词:

bash📋 复制

请用 Python + Playwright 为上面的 11 个测试用例生成自动化测试脚本。要求:1. 包含登录功能(所有测试用例的前置步骤)2. 每个用例一个独立函数3. 包含断言检查4. 失败时自动截图5. 输出测试结果到 JSON 文件6. 添加详细注释,方便新人理解7. 使用 Page Object 模式,便于维护

Hermes 会生成类似下面的脚本:

bash📋 复制

#!/usr/bin/env python3"""电商后台商品管理功能回归测试脚本使用 Playwright 进行浏览器自动化测试测试范围:新增商品 + 查询商品生成:Hermes Agent"""from playwright.sync_api import sync_playwright, expectimport jsonfrom datetime import datetimeimport os# ==================== 配置区域 ====================BASE_URL = "http://localhost:5000"LOGIN_URL = f"{BASE_URL}/login"PRODUCTS_URL = f"{BASE_URL}/products#manage"TEST_ACCOUNT = {"username": "admin""password""123456"}# 创建截图目录os.makedirs("screenshots", exist_ok=True)# ==================== Page Object 类 ====================class LoginPage:    """登录页面对象"""    def __init__(self, page):        self.page = page    def navigate(self):        """打开登录页面"""        self.page.goto(LOGIN_URL, timeout=10000)        return self    def login(self, username, password):        """执行登录"""        self.page.fill("#username", username)        self.page.fill("#password", password)        self.page.click("#login-btn")        self.page.wait_for_timeout(2000)        return self    def is_logged_in(self):        """验证是否登录成功"""        # 检查是否跳转到后台页面        return "/products" in self.page.url or "/dashboard" in self.page.urlclass ProductPage:    """商品管理页面对象"""    def __init__(self, page):        self.page = page    def navigate(self):        """打开商品管理页面"""        self.page.goto(PRODUCTS_URL, timeout=10000)        self.page.wait_for_timeout(2000)        return self    # ----- 新增商品相关方法 -----    def click_add_product(self):        """点击添加商品按钮"""        self.page.click("#add-btn")        self.page.wait_for_timeout(1000)        return self    def fill_product_name(self, name):        """输入商品名称"""        if name:            self.page.fill("#product-name", name)        return self    def fill_product_price(self, price):        """输入商品价格"""        if price is not None:            self.page.fill("#product-price"str(price))        return self    def fill_product_stock(self, stock):        """输入商品库存"""        if stock is not None:            self.page.fill("#product-stock"str(stock))        return self    def submit_add_product(self):        """提交添加商品表单"""        self.page.click("#add-btn")        self.page.wait_for_timeout(2000)        return self    def get_success_message(self):        """获取成功提示信息"""        try:            return self.page.text_content(".success-message")        except:            return None    def get_error_message(self):        """获取错误提示信息"""        try:            return self.page.text_content(".error-message") or self.page.text_content(".alert")        except:            return None    # ----- 查询商品相关方法 -----    def fill_search_keyword(self, keyword):        """输入搜索关键词"""        if keyword:            self.page.fill("#search-input", keyword)        return self    def fill_min_price(self, price):        """输入最低价格"""        if price is not None:            self.page.fill("#min-price"str(price))        return self    def fill_max_price(self, price):        """输入最高价格"""        if price is not None:            self.page.fill("#max-price"str(price))        return self    def click_search(self):        """点击查询按钮"""        self.page.click("#search-btn")        self.page.wait_for_timeout(2000)        return self    def click_reset(self):        """点击重置按钮"""        self.page.click("#reset-btn")        self.page.wait_for_timeout(1000)        return self    def get_product_count(self):        """获取商品列表数量"""        try:            rows = self.page.query_selector_all("#product-table tbody tr")            return len(rows)        except:            return 0    def is_empty_result(self):        """检查是否为空结果"""        try:            empty_msg = self.page.text_content(".empty-message") or self.page.text_content(".no-data")            return empty_msg is not None or self.get_product_count() == 0        except:            return self.get_product_count() == 0# ==================== 测试执行函数 ====================def run_test(case_id, case_name, test_func, expected_success, expected_message=None):    """    执行单个测试用例    参数:        case_id: 用例编号        case_name: 用例名称        test_func: 测试函数        expected_success: 是否预期成功        expected_message: 预期的提示信息    返回:        dict: 测试结果    """    result = {        "case_id": case_id,        "case_name": case_name,        "status""pending",        "actual_message""",        "screenshot": None,        "error": None    }    with sync_playwright() as p:        browser = p.chromium.launch(headless=False)        page = browser.new_page()        try:            # 步骤 1:登录            login_page = LoginPage(page)            login_page.navigate().login(                TEST_ACCOUNT["username"],                TEST_ACCOUNT["password"]            )            # 验证登录成功            if not login_page.is_logged_in():                result["status"] = "failed"                result["actual_message"] = "登录失败"                result["screenshot"] = f"screenshots/{case_id}_login_failed.png"                page.screenshot(path=result["screenshot"])                return result            # 步骤 2:进入商品管理页面            product_page = ProductPage(page)            product_page.navigate()            # 步骤 3:执行具体测试            test_result = test_func(product_page)            # 步骤 4:验证结果            if expected_success:                if test_result.get("success", False):                    result["status"] = "passed"                    result["actual_message"] = test_result.get("message""测试通过")                else:                    result["status"] = "failed"                    result["actual_message"] = test_result.get("message""测试失败")                    result["screenshot"] = f"screenshots/{case_id}_failed.png"                    page.screenshot(path=result["screenshot"])            else:                # 预期失败的场景(如验证错误提示)                if not test_result.get("success", True):                    result["status"] = "passed"                    result["actual_message"] = test_result.get("message""正确捕获错误")                else:                    result["status"] = "failed"                    result["actual_message"] = test_result.get("message""未捕获预期错误")                    result["screenshot"] = f"screenshots/{case_id}_failed.png"                    page.screenshot(path=result["screenshot"])        except Exception as e:            result["status"] = "failed"            result["error"] = str(e)            result["screenshot"] = f"screenshots/{case_id}_error.png"            page.screenshot(path=result["screenshot"])        finally:            browser.close()    return result# ==================== 测试用例定义 ====================def test_add_product_normal(product_page):    """TC001: 正常新增商品"""    product_page.click_add_product()    product_page.fill_product_name("测试商品 001")    product_page.fill_product_price(99.9)    product_page.fill_product_stock(100)    product_page.submit_add_product()    message = product_page.get_success_message()    if message and "成功" in message:        return {"success": True, "message": f"添加成功:{message}"}    return {"success": False, "message": f"添加失败:{message}"}def test_add_product_empty_name(product_page):    """TC002: 商品名称为空"""    product_page.click_add_product()    product_page.fill_product_name("")  # 空名称    product_page.fill_product_price(99.9)    product_page.fill_product_stock(100)    product_page.submit_add_product()    error = product_page.get_error_message()    if error and "名称" in error:        return {"success": False, "message": f"正确提示:{error}"}    return {"success": True, "message": f"未提示错误:{error}"}def test_add_product_negative_price(product_page):    """TC003: 价格为负数"""    product_page.click_add_product()    product_page.fill_product_name("测试商品 002")    product_page.fill_product_price(-100)  # 负数价格    product_page.fill_product_stock(100)    product_page.submit_add_product()    error = product_page.get_error_message()    if error and "价格" in error:        return {"success": False, "message": f"正确提示:{error}"}    return {"success": True, "message": f"未提示错误:{error}"}def test_add_product_zero_price(product_page):    """TC004: 价格为 0"""    product_page.click_add_product()    product_page.fill_product_name("测试商品 003")    product_page.fill_product_price(0)  # 价格为 0    product_page.fill_product_stock(100)    product_page.submit_add_product()    error = product_page.get_error_message()    if error and "价格" in error:        return {"success": False, "message": f"正确提示:{error}"}    return {"success": True, "message": f"未提示错误:{error}"}def test_add_product_negative_stock(product_page):    """TC005: 库存为负数"""    product_page.click_add_product()    product_page.fill_product_name("测试商品 004")    product_page.fill_product_price(99.9)    product_page.fill_product_stock(-50)  # 负数库存    product_page.submit_add_product()    error = product_page.get_error_message()    if error and "库存" in error:        return {"success": False, "message": f"正确提示:{error}"}    return {"success": True, "message": f"未提示错误:{error}"}def test_add_product_large_price(product_page):    """TC006: 价格超过最大值"""    product_page.click_add_product()    product_page.fill_product_name("测试商品 005")    product_page.fill_product_price(999999999)  # 超大价格    product_page.fill_product_stock(100)    product_page.submit_add_product()    # 可能成功也可能失败,取决于系统设计    message = product_page.get_success_message() or product_page.get_error_message()    return {"success": True, "message": f"处理结果:{message}"}def test_search_by_name(product_page):    """TC007: 按名称查询"""    product_page.fill_search_keyword("测试")    product_page.click_search()    count = product_page.get_product_count()    if count > 0:        return {"success": True, "message": f"查询到 {count} 个商品"}    return {"success": False, "message""未查询到商品"}def test_search_by_price_range(product_page):    """TC008: 按价格范围查询"""    product_page.fill_min_price(50)    product_page.fill_max_price(150)    product_page.click_search()    count = product_page.get_product_count()    return {"success": True, "message": f"查询到 {count} 个商品"}def test_search_combined(product_page):    """TC009: 组合查询"""    product_page.fill_search_keyword("测试")    product_page.fill_min_price(50)    product_page.fill_max_price(150)    product_page.click_search()    count = product_page.get_product_count()    return {"success": True, "message": f"查询到 {count} 个商品"}def test_search_no_result(product_page):    """TC010: 查询无结果"""    product_page.fill_search_keyword("不存在的商品 XYZ")    product_page.click_search()    if product_page.is_empty_result():        return {"success": True, "message""正确显示空结果"}    return {"success": False, "message""未显示空结果"}def test_reset_search(product_page):    """TC011: 重置查询"""    # 先输入一些查询条件    product_page.fill_search_keyword("测试")    product_page.fill_min_price(50)    product_page.click_search()    # 点击重置    product_page.click_reset()    # 验证查询条件是否清空(这里简化验证)    return {"success": True, "message""重置完成"}# ==================== 主测试函数 ====================def main():    """主测试函数"""    print("=" * 60)    print("电商后台商品管理功能回归测试")    print("=" * 60)    # 定义所有测试用例    test_cases = [        {"case_id": "TC001""case_name""正常新增商品""test_func": test_add_product_normal, "expected_success": True},        {"case_id": "TC002""case_name""商品名称为空""test_func": test_add_product_empty_name, "expected_success": False},        {"case_id": "TC003""case_name""价格为负数""test_func": test_add_product_negative_price, "expected_success": False},        {"case_id": "TC004""case_name""价格为 0""test_func": test_add_product_zero_price, "expected_success": False},        {"case_id": "TC005""case_name""库存为负数""test_func": test_add_product_negative_stock, "expected_success": False},        {"case_id": "TC006""case_name""价格超过最大值""test_func": test_add_product_large_price, "expected_success": True},        {"case_id": "TC007""case_name""按名称查询""test_func": test_search_by_name, "expected_success": True},        {"case_id": "TC008""case_name""按价格范围查询""test_func": test_search_by_price_range, "expected_success": True},        {"case_id": "TC009""case_name""组合查询""test_func": test_search_combined, "expected_success": True},        {"case_id": "TC010""case_name""查询无结果""test_func": test_search_no_result, "expected_success": True},        {"case_id": "TC011""case_name""重置查询""test_func": test_reset_search, "expected_success": True},    ]    # 执行测试    results = []    for case in test_cases:        print(f"\n执行 {case['case_id']}: {case['case_name']}...")        result = run_test(            case["case_id"],            case["case_name"],            case["test_func"],            case["expected_success"]        )        results.append(result)        # 打印结果        status_icon = "✅" if result["status"] == "passed" else "❌"        print(f"{status_icon} {case['case_id']}: {result['status']}")        print(f"   结果:{result['actual_message']}")    # 生成测试报告    report = {        "test_time": datetime.now().isoformat(),        "module""商品管理",        "total_cases"len(results),        "passed"sum(1 for r in results if r["status"] == "passed"),        "failed"sum(1 for r in results if r["status"] == "failed"),        "results": results    }    # 保存报告    with open("product_test_report.json", "w", encoding="utf-8") as f:        json.dump(report, f, ensure_ascii=False, indent=2)    # 打印汇总    print("\n" + "=" * 60)    print("测试汇总")    print("=" * 60)    print(f"总用例数:{report['total_cases']}")    print(f"通过:{report['passed']} ✅")    print(f"失败:{report['failed']} ❌")    pass_rate = report['passed'] / report['total_cases'] * 100 if report['total_cases'] > 0 else 0    print(f"通过率:{pass_rate:.1f}%")    print(f"\n详细报告已保存到:product_test_report.json")if __name__ == "__main__":    main()

07

第四步:运行测试脚本

在终端执行以下命令:

bash📋 复制

# 1. 安装依赖(首次执行需要)pip install playwright# 2. 安装浏览器playwright install chromium# 3. 创建截图目录mkdir -p screenshots# 4. 运行测试python product_test.py

执行过程

你会看到类似这样的输出:

bash📋 复制

============================================================电商后台商品管理功能回归测试============================================================执行 TC001: 正常新增商品...✅ TC001: passed   结果:添加成功:商品添加成功执行 TC002: 商品名称为空...✅ TC002: passed   结果:正确提示:请输入商品名称执行 TC003: 价格为负数...✅ TC003: passed   结果:正确提示:价格必须大于 0执行 TC004: 价格为 0...✅ TC004: passed   结果:正确提示:价格必须大于 0执行 TC005: 库存为负数...✅ TC005: passed   结果:正确提示:库存必须大于等于 0执行 TC006: 价格超过最大值...✅ TC006: passed   结果:处理结果:价格超出范围执行 TC007: 按名称查询...✅ TC007: passed   结果:查询到 5 个商品执行 TC008: 按价格范围查询...✅ TC008: passed   结果:查询到 3 个商品执行 TC009: 组合查询...✅ TC009: passed   结果:查询到 2 个商品执行 TC010: 查询无结果...✅ TC010: passed   结果:正确显示空结果执行 TC011: 重置查询...✅ TC011: passed   结果:重置完成============================================================测试汇总============================================================总用例数:11通过:11 ✅失败:0 ❌通过率:100.0%详细报告已保存到:product_test_report.json

08

JSON 报告内容

打开 product_test_report.json,你会看到:

bash📋 复制

{  "test_time": "2026-04-08T19:30:00",  "module": "商品管理",  "total_cases": 11,  "passed": 11,  "failed": 0,  "results": [    {      "case_id": "TC001",      "case_name": "正常新增商品",      "status": "passed",      "actual_message": "添加成功:商品添加成功",      "screenshot": null,      "error": null    },    {      "case_id": "TC002",      "case_name": "商品名称为空",      "status": "passed",      "actual_message": "正确提示:请输入商品名称",      "screenshot": null,      "error": null    }    // ... 其他用例  ]}

HTML 可视化报告

使用第 3 篇中的 HTML 报告生成脚本,可以生成可视化的测试报告。


09

多走一步:让 Hermes 帮你「造数据 + 洗环境」

列表类用例最怕空表假绿。可以在跑 TC007 之前加一轮对话:

bash📋 复制

请写一个 Python 脚本(Playwright 或 requests,任选其一):登录后新增 5 条测试商品,名称带统一前缀 TEST_AUTO_,价格和库存各不相同,便于后续查询用例断言。并提供测试结束后的清理建议(按名称前缀删除或标记)。

这样查询 / 组合 / 无结果几条用例才不容易变成“嘴上通过”。


10

关键提示词模板(可直接复制)

你可以直接复制使用:

bash📋 复制

【任务拆解】我要对 [系统名称] 的 [功能模块] 进行测试。系统信息:[URL、账号、元素 ID 等]请帮我拆解测试任务为可执行的步骤。【测试用例生成】请把上面的测试步骤转换成可执行的测试用例表格,包含:用例编号、功能模块、用例名称、前置条件、测试步骤、测试数据、预期结果、优先级。【脚本生成】请用 Python + Playwright 为上面的测试用例生成自动化测试脚本。要求:包含登录功能、每个用例独立函数、包含断言、失败截图、输出 JSON 报告、添加详细注释、使用 Page Object 模式。【报告生成】请把 JSON 测试报告转换成 HTML 格式的可视化报告。要求:包含汇总信息、表格展示详情、通过/失败颜色标记、附截图、样式专业。【结果分析】这是测试结果:[粘贴测试数据]请分析测试覆盖是否充分,还有哪些边界场景需要补充,给出改进建议。

11

我建议你重点人审的三处

  • TC006(超大价格) :不同产品会「拒绝 / 截断 / 科学计数」,自动化里别写死一种文案,先跟研发对齐规则。
  • 查询类用例:列表排序、默认分页会导致“有数据但看不见”,断言尽量绑行内文案接口返回值,而不是只数 tr
  • 新增与查询耦合:先保证数据工厂脚本稳定,再谈通过率;否则 flakiness 会伪装成“脚本不行”。

12

Q1:元素 ID 找不到怎么办?

A:让 Hermes 帮你生成元素定位脚本:

bash📋 复制

请帮我生成一个 Python 脚本,用 Playwright 打开商品管理页面,打印出所有输入框和按钮的 ID、name、class 等属性,方便我找到正确的元素定位器。

Q2:测试数据怎么准备?

A:让 Hermes 生成测试数据准备脚本:

bash📋 复制

请帮我生成一个 Python 脚本,在测试前先准备测试数据:- 添加 5 个测试商品(名称、价格、库存不同)- 数据要覆盖各种场景(正常价格、边界价格等)

Q3:如何用 Hermes 优化测试脚本?

A:把现有脚本发给 Hermes,让它优化:

bash📋 复制

请帮我优化这个测试脚本:1. 添加重试机制(失败后重试 3 次)2. 添加更详细的日志输出3. 添加测试执行时间统计4. 优化代码结构,提高可读性

13

下一篇预备选题:订单管理(状态流转 + 列表筛选)或工程化加餐(数据工厂、定时报告推飞书群)。留言「订单 / 报表 / 秒杀」里哪个多,我先写哪个。


资源备忘: - Hermes GitHub:github.com/NousResearc…


谢谢你看到这里。

做商品后台测试的同学,留言区丢我你最痛的一点(元素定位 / 数据准备 / 断言 / 报告),我按热度整理成答疑篇。


动手试试

  1. 先发商品管理页 + 登录方式,要一版「只有表格、没有代码」的用例草案,看和你的直觉差多少。
  2. 再打开本文「关键提示词模板」,生成可落 Playwright 的第二版。

P.S. 模块越复杂,越要相信:页面即需求入口;平台与 skills 不是对手,是你可以在第二阶段再上的「收纳层」。

本公众号可以搜索testzhouzhougz

如有任何问题可联系周周个人微信:testzhouzhou;