发布时间:2026/8/30 18:20:48
AI自动化测试:用Skill固化Web测试经验,告别不稳定脚本 AI 写自动化测试真正难的从来不是“写代码”而是让 AI 知道页面元素该用什么方式定位、等待逻辑怎么写才稳定、断言要对应哪些业务规则、测试报告要输出到什么程度。这些知识靠一长串 Prompt 根本装不下但可以结构化到一个 Skill 里。很多测试同学用 AI 助手时会遇到同样的尴尬生成的脚本第一眼很完整一运行就崩让它改一个定位符它把整个文件重写了让它补一条用例逻辑和页面流程完全对不上。问题不是模型能力不够而是我们没有把“测试这门手艺”的系统知识提供给模型。这篇文章要解决的就是怎么把 Web 自动化测试的领域经验封装成一个可复用的 Skill。我会从一个可以直接照抄的工程讲起覆盖 Skill 的目录结构、完整代码、Markdown 报告模板、运行验证和常见问题排查。读完你能在自己的项目里搭建一套专属的 AI 测试 Skill并理解它背后真正提升效率的机制。1. 这篇文章真正要解决的问题1.1 AI 写自动化测试的常见翻车现场先看几个真实场景。场景一让 AI 写一组登录页测试用例。它很快给出一个 Playwright 脚本看起来逻辑完整有页面打开、输入用户名密码、点击登录、断言跳转。但一运行脚本在第一步就超时了。原因是它生成的是固定的time.sleep(3)页面加载慢一点就崩快一点又白白等三秒。场景二让 AI 定位一个按钮。它给了page.locator(text提交).click()。结果页面上有两处“提交”一个在导航栏一个在表单底部。脚本随机点到了一个不可见元素测试报错。如果团队里有一个懂测试的人他会告诉你优先用get_by_role(button, name提交)或者给按钮加上稳定的>python -m venv .venv source .venv/bin/activate # Windows 使用 .venv\Scripts\activate pip install playwright playwright install chromium这里一定要执行playwright install chromium它会下载 Playwright 需要的浏览器内核。如果跳过这一步脚本运行时会直接报“可执行文件不存在”的错误。3.3 准备一个可测试的本地页面为了不依赖外网环境我们生成一个简单的本地页面。创建demo/index.html!-- 文件路径demo/index.html -- !DOCTYPE html html langzh-CN head meta charsetUTF-8 title测试页面/title style #app { max-width: 600px; margin: 50px auto; font-family: sans-serif; } .status { color: green; font-weight: bold; } /style /head body div idapp h1欢迎使用 AI 测试 Skill/h1 p这是一个用于验证 Web 自动化测试 Skill 的本地页面。/p button idsubmit-btn提交/button input idsearch-input placeholder请输入关键词 / /div /body /html在项目根目录执行python -m http.server 8080然后浏览器访问http://127.0.0.1:8080/看到页面说明本地环境正常。如果不想在本机起服务也可以用公开测试站点但要注意不要对没有授权的站点做高频自动化访问。本地页面是最稳定、最安全的选择。4. 测试 Skill 的目录结构与设计思路4.1 整体目录结构一个 Web 自动化测试 Skill 可以这样组织web-test-skill/ ├── SKILL.md ├── scripts/ │ ├── run_web_test.py │ └── generate_test_case.py ├── examples/ │ └── smoke_test_demo.md ├── docs/ │ ├── best_practices.md │ └── troubleshooting.md └── requirements.txt先建目录mkdir -p web-test-skill/scripts mkdir -p web-test-skill/examples mkdir -p web-test-skill/docs4.2 每个文件的作用SKILL.md是 Skill 的入口AI 会优先读取它。scripts/run_web_test.py是核心执行脚本负责访问页面、检查元素、生成报告。scripts/generate_test_case.py是辅助脚本用于批量生成测试用例 Markdown 骨架。examples/存放调用示例AI 生成新脚本时可以参考。docs/存放最佳实践和排查手册进一步增强 Skill 的知识量。requirements.txt声明 Python 依赖。这种拆分的好处是指令和可执行能力分离。SKILL.md负责告诉 AI“怎么做”scripts/负责真正执行docs/负责提供深层知识。AI 在运行 Skill 时可以根据任务需要调用不同的文件。4.3 Skill 的加载机制说明不同 AI 工具对 Skill 的目录约定不完全一样。比较常见的做法是把 Skill 目录放到项目下的.claude/skills/或类似的约定目录中主文件名固定为SKILL.md。例如cp -r web-test-skill .claude/skills/web-test-skill如果你的工具支持自定义 Skill 加载路径也可以配置到公共目录供多个项目复用。具体字段名和加载语法请以你正在使用的工具文档为准。本文重点是教你把 Skill 的内容搭起来工具差异不影响核心设计。5. 完整代码实现这一节是全文的重点。我会按文件逐个给出完整代码并解释关键逻辑。你可以直接复制改一改路径就能用。5.1 SKILL.md 主文件SKILL.md是整个 Skill 的核心。AI 面对测试任务时会通过这个文件了解你的测试规范。--- name: web-test-skill description: Web 自动化测试实战技能。适用于使用 Playwright 编写和执行 UI 自动化测试、定位页面元素、设计测试断言、生成 Markdown 测试报告的场景。当用户需要做 Web 端功能回归、冒烟测试、页面元素定位或测试用例设计时优先使用本 Skill。 allowed-tools: - Bash - Read - Write - Edit --- # Web 自动化测试 Skill ## 使用流程 1. 先确认被测页面 URL能本地访问就优先本地访问不要直接对没有授权的线上服务发起自动化请求。 2. 编写 Playwright 脚本时先明确要验证的业务场景再编写步骤。 3. 每条断言必须有明确的业务含义失败信息要包含期望值、实际值和定位信息。 4. 测试结束后生成 Markdown 报告说明总体结论和失败分析。 ## 定位策略优先级 从高到低依次选择 1. get_by_test_id 或 data-testid 2. get_by_role如按钮、链接、输入框 3. get_by_label / get_by_placeholder 4. CSS 选择器 5. XPath仅在以上方法都不满足时使用 ## 等待与稳定性要求 - 禁止直接使用 time.sleep(3) 等待元素这会降低脚本稳定性。 - 优先使用 wait_for_selector、wait_for_load_state、expect 等显式等待。 - 所有超时时间必须可配置默认超时为 10 秒。 ## 断言规范 - 断言内容必须对应业务规则而不是只判断元素存在。 - 失败信息必须包含期望值、实际值和定位信息。 - 不要把多个断言写在同一行。 - 断言失败时应保留当前页面截图作为排查依据。 ## 报告要求 - 输出格式为 Markdown。 - 报告头部包含测试时间、测试地址、执行环境。 - 每个检查项的状态必须是通过、失败、阻塞。 - 截图仅作为辅助证据最终结论以断言结果为准。 ## 脚本调用约定 - 执行冒烟测试时使用 python scripts/run_web_test.py。 - 生成测试用例时使用 python scripts/generate_test_case.py。 - 所有路径均相对于 Skill 根目录。关键点在于description要写得足够明确这样 AI 才能在多种任务中准确识别什么情况下应该加载这个 Skill。allowed-tools声明了 Skill 运行时允许使用的权限范围按照最小权限原则配置即可。5.2 自动化测试执行脚本 run_web_test.py这个脚本完成三件事访问被测页面、执行检查项、输出 Markdown 报告。# 文件路径web-test-skill/scripts/run_web_test.py import argparse import os import sys import time from datetime import datetime from playwright.sync_api import sync_playwright def build_report(url, results, screenshot_path): lines [ # Web 自动化测试报告, , f- 测试时间{datetime.now().strftime(%Y-%m-%d %H:%M:%S)}, f- 测试地址{url}, f- 截图文件{screenshot_path}, , ## 检查项结果, , | 检查项 | 结果 | 说明 |, | --- | --- | --- |, ] for item in results: status 通过 if item[ok] else 失败 lines.append(f| {item[name]} | {status} | {item[message]} |) return \n.join(lines) def main(): parser argparse.ArgumentParser(description基于 Playwright 的 Web 自动化测试脚本) parser.add_argument(--url, requiredTrue, help被测页面 URL) parser.add_argument(--selector, defaultbody, help核心元素选择器) parser.add_argument(--expected-title, default, help预期页面标题片段) parser.add_argument(--timeout, typeint, default10000, help元素等待超时时间单位毫秒) parser.add_argument(--output-dir, defaultreports, help报告输出目录) parser.add_argument(--headless, actionstore_true, help是否以无头模式运行) args parser.parse_args() os.makedirs(args.output_dir, exist_okTrue) results [] with sync_playwright() as p: browser p.chromium.launch(headlessargs.headless) page browser.new_page() # 检查点 1页面是否能成功访问 try: response page.goto(args.url, wait_untilload, timeoutargs.timeout) results.append({ name: 页面访问, ok: response is not None and response.ok, message: fHTTP {response.status} if response else 无响应, }) except Exception as exc: results.append({name: 页面访问, ok: False, message: str(exc)}) # 检查点 2页面标题是否符合预期 if args.expected_title: actual_title page.title() results.append({ name: 页面标题, ok: args.expected_title in actual_title, message: f期望包含「{args.expected_title}」实际为「{actual_title}」, }) # 检查点 3关键元素是否可见 try: page.wait_for_selector(args.selector, timeoutargs.timeout) results.append({ name: 关键元素, ok: True, message: f选择器 {args.selector} 已可见, }) except Exception as exc: results.append({name: 关键元素, ok: False, message: str(exc)}) screenshot_path os.path.join( args.output_dir, fscreenshot_{int(time.time())}.png ) page.screenshot(pathscreenshot_path) browser.close() report build_report(args.url, results, screenshot_path) report_path os.path.join(args.output_dir, report.md) with open(report_path, w, encodingutf-8) as f: f.write(report) print(report) failed [r for r in results if not r[ok]] sys.exit(1 if failed else 0) if __name__ __main__: main()脚本的核心逻辑有三个设计值得注意第一检查项被设计成列表每个检查项都有独立的成功/失败状态。这样即使一个检查项失败其他检查项也不会被跳过报告内容会更完整。第二所有等待都通过 Playwright 的wait_for_selector(timeoutargs.timeout)完成而不是time.sleep。这是 Web 自动化测试稳定性的关键。第三脚本结束时根据是否有失败项返回不同的退出码。这样把脚本接入 CI 流水线时可以直接用退出码判断测试是否通过。5.3 测试用例生成辅助脚本 generate_test_case.py除了执行冒烟测试Skill 还应该帮助 AI 快速生成结构化的测试用例文档。这个辅助脚本根据传入的步骤 JSON生成一个 Markdown 用例骨架。# 文件路径web-test-skill/scripts/generate_test_case.py import argparse import json from datetime import datetime from pathlib import Path TEMPLATE # 测试用例{case_name} ## 前置条件 - [ ] 被测环境已部署 - [ ] 测试数据已准备 ## 操作步骤 | 步骤 | 操作 | 预期结果 | 实际结果 | 是否通过 | | --- | --- | --- | --- | --- | {steps} ## 自动化脚本要点 python # TODO: 根据上述步骤使用本 Skill 的定位与断言规范编写 # 可参考 examples/ 下的示例。备注优先级{priority}创建时间{created_at} def main(): parser argparse.ArgumentParser(description生成测试用例 Markdown 骨架) parser.add_argument(--name, requiredTrue, help用例名称) parser.add_argument(--steps, help步骤 JSON 数组) parser.add_argument(--priority, defaultP2, help优先级 P0/P1/P2) args parser.parse_args()steps [] if args.steps: steps json.loads(args.steps) step_lines [] for idx, step in enumerate(steps, 1): op step.get(操作, ) expected step.get(预期, ) step_lines.append(f| {idx} | {op} | {expected} | | |) if not step_lines: step_lines.append(| 1 | 打开被测页面 | 页面正常加载 | | |) content TEMPLATE.format( case_nameargs.name, steps\n.join(step_lines), priorityargs.priority, created_atdatetime.now().strftime(%Y-%m-%d %H:%M:%S), ) out_path Path(fcases/{args.name}.md) out_path.parent.mkdir(exist_okTrue, parentsTrue) out_path.write_text(content, encodingutf-8) print(f用例已生成{out_path})ifname main: main()执行示例 bash python scripts/generate_test_case.py \ --name 登录成功用例 \ --steps [{操作:打开登录页,预期:页面加载完成},{操作:输入正确用户名和密码,预期:输入成功},{操作:点击登录按钮,预期:跳转到首页右上角显示用户名}] \ --priority P0这个脚本的意义在于它把“测试用例应该长什么样”固化了下来。AI 在编写用例时不再自由发挥格式而是按照这个骨架输出团队评审和后续统计都更方便。5.4 报告模板 report_template.md为了让 Skill 生成的报告风格统一再准备一个 Markdown 报告模板# {测试项目} 自动化测试报告 - 执行时间{time} - 执行人{owner} - 执行环境{env} ## 汇总 - 用例总数{total} - 通过数{passed} - 失败数{failed} - 通过率{pass_rate} ## 结果明细 {result_table} ## 失败分析 {failure_analysis} ## 结论 {conclusion}这个模板可以放在docs/report_template.md里。当 AI 需要生成完整测试报告时要求它严格按模板填充保证团队所有报告结构一致。5.5 依赖声明 requirements.txt在 Skill 根目录添加依赖文件# 文件路径web-test-skill/requirements.txt playwright1.40.0如果需要用 pytest 体系做更细粒度的用例管理可以再加pytest7.0.0 pytest-playwright0.4.0安装命令pip install -r requirements.txt5.6 示例文档 examples/smoke_test_demo.md为了增强 Skill 的引导能力可以在examples/下放一个冒烟测试示例AI 在生成新脚本时可以参考。# 冒烟测试示例本地测试页面 ## 目标 验证本地测试页面可以正常打开标题正确核心按钮可见。 ## 命令 bash python scripts/run_web_test.py \ --url http://127.0.0.1:8080/ \ --selector #submit-btn \ --expected-title 测试页面 \ --output-dir reports预期结果页面访问检查项通过页面标题检查项通过关键元素检查项通过把示例写进 Skill 目录相当于给 AI 一本“别人已经跑通的作业”它生成代码时的模仿成本会低很多。 ## 6. 运行结果与效果验证 ### 6.1 把 Skill 接入项目 先把 Skill 目录复制到 AI 工具的 Skill 加载目录以常见的 .claude/skills/ 约定为例 bash cp -r web-test-skill .claude/skills/web-test-skill然后确认目录结构find .claude/skills/web-test-skill -maxdepth 2 -type f正常输出应该包含.claude/skills/web-test-skill/SKILL.md .claude/skills/web-test-skill/requirements.txt .claude/skills/web-test-skill/scripts/run_web_test.py .claude/skills/web-test-skill/scripts/generate_test_case.py6.2 运行冒烟测试启动本地页面python -m http.server 8080执行 Skill 中的测试脚本python .claude/skills/web-test-skill/scripts/run_web_test.py \ --url http://127.0.0.1:8080/ \ --selector #submit-btn \ --expected-title 测试页面 \ --output-dir reports \ --headless预期输出类似# Web 自动化测试报告 - 测试时间2025-01-01 12:00:00 - 测试地址http://127.0.0.1:8080/ - 截图文件reports/screenshot_1704000000.png ## 检查项结果 | 检查项 | 结果 | 说明 | | --- | --- | --- | | 页面访问 | 通过 | HTTP 200 | | 页面标题 | 通过 | 期望包含「测试页面」实际为「测试页面」 | | 关键元素 | 通过 | 选择器 #submit-btn 已可见 |同时reports/report.md和截图文件会生成到本地。6.3 如何判断 Skill 生效判断 Skill 是否真正被 AI 加载可以从两个角度验证第一直接运行脚本确认脚本本身可用。这是最基础的验证。第二在 AI 对话中描述一个测试需求观察它是否引用了 Skill 中的规范。例如你问“用我们的测试规范写一个登录页检查”如果 AI 自动使用了get_by_role、wait_for_selector并主动要求生成 Markdown 报告说明 Skill 已经在起作用。如果 AI 完全没有反应大概率是 Skill 目录位置或描述信息没有配置正确。可以检查描述里是否包含了“Web 自动化测试”“Playwright”“测试报告”等触发词。7. 常见问题与排查思路实际落地时会遇到的问题往往不在代码本身而在环境、工具集成和稳定性上。下面列出高频问题。问题现象可能原因排查方式解决方案运行脚本报“Executable doesnt exist”未安装 Playwright 浏览器内核检查 Playwright 安装目录执行playwright install chromium打开页面超时本地服务端口不对或 URL 写错浏览器手动访问 URL 确认页面可打开检查--url确认服务已启动元素定位不到选择器过期或在 iframe / shadow DOM 中打开浏览器 DevTools 验证选择器能命中唯一元素改用>期望按钮文案为「提交订单」实际为「提交」。而不是locator not found8.5 使用 testid 作为首选定位方式如果项目还在开发阶段建议在关键交互元素上统一添加>

相关新闻

2026/8/30 18:20:48

CATIA CAA二次开发实战:构建参数化刀具设计自动化框架

简介:在机械设计与制造领域,参数化设计与自动化是提升效率、保证质量的关键技术。其核心原理是通过编程将设计规则、专家经验和企业标准固化为可执行的逻辑,实现从参数输入到三维模型、工程图及工艺文件的自动生成。这项技术的核心价值在于将…

2026/8/30 18:20:48

一周刷完330道Python练习题,就能变编程大神?

还在收藏“Python630道练习题”“Python330道练习题”这类合集吗?我能理解这股冲动:看起来只要把这些题从头刷到尾,一周之后,Python 语法基本掌握,写代码的底气也会足不少。尤其当天真的按照计划连刷几十道题&#xff…

2026/8/30 18:15:48

VB6控件ReSize.ocx与imgctls.ocx注册打包及80040154报错全解析

简介:在Windows软件开发中,ActiveX控件(OCX)是实现界面增强功能的关键组件,尤其对VB6工程而言,控件注册与分发是项目落地的核心环节。理解OCX控件的运作原理,掌握正确的注册方式,能有…

2026/8/30 18:35:49

MySQL下载安装与Navicat连接保姆级教程:免费安全方案

【2026 暑假版】小白必入!MySQL 下载安装与 Navicat 连接教程(保姆级,免费方案)先说明一句题外话:很多同学搜索“Navicat 激活码”“Navicat 破解版”的时候,无非是想把这款数据库图形化工具免费拿下来&…

2026/8/30 18:35:49

Qt+SOEM实现CSV驱动电机的工业级控制范式

简介:本资源是面向嵌入式与工业自动化开发者的技术实践项目,基于Ubuntu 18.04平台,使用Qt框架集成SOEM开源库构建EtherCAT主站,重点实现CSV(周期同步速度)模式下对单台伺服电机的闭环控制——包括正转、反转…

2026/8/30 18:35:49

RBF神经网络在永磁同步电机FOC控制中的应用与实现

简介:本资源是一份面向电机控制方向研究生、电力电子工程师及智能控制算法实践者的MATLAB仿真代码包,聚焦于RBF神经网络与FOC矢量控制深度融合的永磁同步电机(PMSM)速度环优化方案,旨在解决传统PI控制器在负载突变、参…

2026/8/30 18:35:49

Agent 文件传递

1. 问题目前 Agent 已经可以在工作目录中创建和处理文件,但这些文件都保存在后端服务器上,前端无法直接访问。因此需要增加一个中间环节,把 Agent 生成的文件交给用户。这里采用对象存储的方式:Agent生成文件↓ 工作目录↓ 打包↓…

2026/8/30 18:35:49

Cursor 入门指南:从安装到高效使用的 AI 代码编辑器

在实际写代码的过程中,工具选型往往比想象中更影响效率。Cursor 就是这样一款把 AI 能力直接嵌入编辑器流程的编程助手,它既能像普通代码编辑器一样打开项目、搜索文件、运行命令,又能在对话、补全、修改代码时调用大语言模型帮助你完成编码任…

2026/8/30 18:30:49

Qt+OpenCV+Basler工业相机跨平台视觉控制系统开发实战

简介:机器视觉系统通常由图像采集、处理与显示组成,而工业相机的稳定出图与实时算法处理是核心环节。以Basler相机为代表,借助pylon SDK完成底层取流,再通过OpenCV实现边缘检测、ROI定位等算法,最后以Qt构建跨平台GUI&…

2026/8/30 0:03:35

vSound小提琴数字处理器实操指南:从接线到演出的完整配置

电小提琴或者原声小提琴插电演出,第一个绕不开的坎就是声音难听。原声琴的共鸣和空气感一旦进了拾音器,出来的往往是一坨干瘪、发尖、带着奇怪塑料味的信号。我当初第一次把琴接上乐队调音台,直接被主唱吐槽"你这声音像在锯钢丝"。…

2026/8/30 0:03:35

传感器接口IC如何攻克生物化学传感的微弱信号难题?

1. 从电极到比特流:为什么生物化学传感必须依赖专用接口IC 做生物化学传感的人都有过类似的经历:明明传感器本身性能很好,信号输出却一塌糊涂——噪声大、漂移明显、重复性差,怎么调都达不到预期。很多时候问题并不在传感器&#…

2026/8/30 0:03:35

STM32F411CEU6多通道ADC采集:扫描模式+DMA实现详解

1. 多通道 ADC 的用武之地把“Multichannel ADC”和“STM32F411CEU6”这两个关键字放在一起,其实就是嵌入式开发里最常遇到的一类需求:用一块不算贵的 MCU,同时采集多路模拟信号。STM32F411CEU6 是 48 引脚的 Cortex-M4F 主控,主频…

2026/8/30 0:03:35

vSound小提琴数字处理器实操指南:从接线到演出的完整配置

电小提琴或者原声小提琴插电演出,第一个绕不开的坎就是声音难听。原声琴的共鸣和空气感一旦进了拾音器,出来的往往是一坨干瘪、发尖、带着奇怪塑料味的信号。我当初第一次把琴接上乐队调音台,直接被主唱吐槽"你这声音像在锯钢丝"。…

2026/8/30 0:03:35

传感器接口IC如何攻克生物化学传感的微弱信号难题?

1. 从电极到比特流:为什么生物化学传感必须依赖专用接口IC 做生物化学传感的人都有过类似的经历:明明传感器本身性能很好,信号输出却一塌糊涂——噪声大、漂移明显、重复性差,怎么调都达不到预期。很多时候问题并不在传感器&#…

2026/8/30 0:03:35

STM32F411CEU6多通道ADC采集:扫描模式+DMA实现详解

1. 多通道 ADC 的用武之地把“Multichannel ADC”和“STM32F411CEU6”这两个关键字放在一起,其实就是嵌入式开发里最常遇到的一类需求:用一块不算贵的 MCU,同时采集多路模拟信号。STM32F411CEU6 是 48 引脚的 Cortex-M4F 主控,主频…

2026/8/28 16:16:48

实测才敢推 AI论文网站 2026最新测评与推荐

2026年真正好用的AI论文网站,核心看生成的论文质量、低AI味、格式正确、学术适配四大指标。综合实测,千笔AI、ThouPen、豆包、DeepSeek、Grammarly 是当前最值得推荐的梯队,覆盖从免费到付费、从中文到英文、从文科到理工的全场景需求。一、综…

2026/8/28 16:16:50

2026必备!AI论文网站测评:最新推荐与深度对比

2026年真正好用的AI论文网站,核心看生成的论文质量、低AI味、格式正确、学术适配四大指标。综合实测,千笔AI、ThouPen、豆包、DeepSeek、Grammarly 是当前最值得推荐的梯队,覆盖从免费到付费、从中文到英文、从文科到理工的全场景需求。 一、…

2026/8/28 11:06:45

摆脱论文困扰!盘点2026年全网爆红的的AI论文写作工具

一天写完毕业论文在2026年已不再是天方夜谭。2026年最炸裂、实测能大幅提速的AI论文写作工具,覆盖选题构思、文献整理、内容生成、格式排版等核心场景,真正帮你高效搞定论文难题。 一、全流程王者:一站式搞定论文全链路(一天定稿首…