当前位置: 首页 > news >正文

AI测试实战:用Skill+Playwright构建Web自动化测试体系

1. 为什么“Skill”突然变成了 AI 测试的关键词

先抛一个结论:Skill 不是新的编程语言,也不是某个厂商的专有格式,它是把“一段可复用的 AI 能力”打包成标准文件结构的方法。

过去半年,凡是接触过 Claude Code、Codex、Cursor 或各类 AI Agent 的测试工程师,都会频繁看到一个目录里放着SKILL.md文件。很多人的第一反应是:“这不就是给 AI 看的说明书吗?”这句话只对了一半。

真正的关键点在于:Skill 本质上是在给 AI 大模型“外挂记忆和工具”,让 AI 不需要每次重新理解测试流程,而是直接读取一套写好的方法、脚本和注意事项,然后按步骤执行。

传统 Web 自动化测试,我们通常会经历这样一个过程:

  1. 用 Selenium 或 Playwright 写脚本;
  2. 把脚本组织成 Page Object 模式;
  3. 封装公共方法,比如等待元素、读取数据;
  4. 写好测试报告;
  5. 重新配置 CI 流水线;
  6. 在本地或服务器上跑。

这个过程最耗时的不是写代码,而是“切换上下文”。当你从写登录用例切到写订单流程用例时,你要重新回忆项目里有哪些选择器、有哪些公共 API、哪些场景容易出问题。

而有了 Skill 之后,流程变化非常明显:

  • AI 自动读取SKILL.md,理解测试项目的目录结构和约定;
  • AI 按照 Skill 里定义的步骤,直接生成完整的 Web 自动化测试脚本;
  • AI 自动调用封装好的 Playwright 公共模块;
  • 测试工程师只负责评审代码、补充边界场景、运行脚本和排查失败原因。

说白了,Skill 降低的是“人把业务规则翻译成测试代码”的成本,而不是“AI 生成代码”的成本。这也解释了为什么很多测试团队试用 AI 写自动化测试后,评价两极分化:用了 Skill 的团队觉得效率翻倍,没用 Skill 的团队觉得 AI 总是写出“看起来对、跑起来废”的脚本。

本文会直接给出一个可照抄的 Web 自动化测试 Skill 完整方案,包括目录结构、SKILL.md写法、Playwright 脚本、md 文档模板、运行验证和常见坑。整篇文章不追求“包装成 100 倍效率神器”,而是把一眼能用、拿到手就能跑的细节讲透。

如果你是以下读者,这篇文章会很有用:

  • 想用 AI 辅助完成 Web 自动化测试,但不知道如何约束 AI 输出质量的测试工程师;
  • 在团队里负责测试工具链,想沉淀一套可复用的自动化测试能力;
  • 正在准备 AI 测试相关面试,需要理解 Agent、Skill、代码生成这三者之间关系的候选人;
  • 已经接触过 Playwright 但希望把它和 AI 工作流结合起来的开发者。

2. Skill 在 AI 测试体系里的定位

2.1 从 Agent 到 Skill:AI 测试的三种角色

要理解 Skill,先得看它在 AI 测试体系里的位置。一个典型的 AI 测试 Agent 工作流里,通常有三个层次:

层次名称作用举例
第一层Agent负责任务拆解、决策、调用工具用户说“帮我跑一下登录页的自动化测试”,Agent 决定用什么工具
第二层Skill提供特定领域的知识、步骤、脚本模板登录测试 Skill、订单流程测试 Skill、断言规范 Skill
第三层Tool / API执行具体动作Playwright 启动浏览器、读取测试报告、执行命令

Agent 是大脑,Skill 是操作手册,Tool 是手脚。

这个比喻很关键。如果只给 AI 一个 Playwright 工具,它确实能写代码,但它不知道:

  • 你的测试项目里有哪些公共函数;
  • 你期望的等待策略是什么;
  • 你的环境变量从哪个文件读取;
  • 哪些用例在 CI 上容易跑挂;
  • 测试报告应该输出成什么格式。

这些都属于“领域知识”,而 Skill 就是把这些知识结构化、文件化的载体。

2.2 为什么传统自动化测试方案中“测试代码”很难直接复用到 AI 场景

传统测试代码的复用方式是“函数复用”和“类继承”,但这套方式对 AI 并不友好。原因在于:

  • AI 不理解你的代码架构,除非你告诉它。你把一个封装得很漂亮的 BasePage 类丢给 AI,它可能不知道哪个方法是刷新页面,哪个方法是等待元素。
  • AI 生成代码时容易偏离团队约定。你的团队习惯用>web-test-skill/ ├── SKILL.md # Skill 的主文件,AI 首先读取 ├── scripts/ │ ├── login_test.py # 登录场景的自动化脚本 │ ├── order_test.py # 订单流程的自动化脚本 │ ├── utils.py # 公共工具函数 │ └── config.py # 配置信息 ├── examples/ │ ├── quick_start.md # 快速上手文档 │ └── demo_test.py # 演示测试脚本 ├── docs/ │ ├── selector_guide.md # 元素定位规范 │ └── trouble_shooting.md # 常见问题 └── requirements.txt # Python 依赖列表

    从 AI 的角度看,这个结构最重要的文件就是SKILL.md。AI Agent 在判断是否使用某个 Skill 时,通常先读取它的描述信息,然后加载主文件。如果主文件写得不清不楚,AI 就会随机发挥,效果自然不可控。

    4.1 SKILL.md 的编写要点

    SKILL.md是标准 Markdown 文件,对 AI 来说它是“指令式文档”,对团队成员来说它是“可读性极强的手册”。核心结构如下:

    --- name: web-test-skill description: 用于 Web 端 UI 自动化测试的通用 Skill。支持登录、订单流程、页面元素断言等场景。 --- # Web 自动化测试 Skill ## 使用场景 适用于以下情况: - 需要对 Web 页面进行端到端自动化测试 - 需要生成 Playwright 脚本 - 需要排查 UI 自动化测试失败原因 ## 前置条件 1. Python 3.9 以上 2. 已安装 playwright 3. 已安装浏览器内核(playwright install chromium) ## 步骤 1. 分析测试需求,确定测试页面和测试数据 2. 在 scripts/utils.py 中复用公共方法 3. 按照模板生成测试脚本 4. 运行测试并输出结果 ## 代码模板 参考 examples/demo_test.py ## 常见错误 - 不要使用 time.sleep 等待元素,使用 Playwright 自动等待 - 不要针对动态数据写死断言,使用模糊匹配

    需要提醒的是,description字段要写得明确且克制。不要写“这个 Skill 能做所有事”,而要写清楚它“擅长什么、不擅长什么”。AI 在模型层面会做工具选择,描述越准确,选错的概率越低。

    5. 完整代码实现:一套可照抄的 Web 测试 Skill

    下面我会给出三个核心文件,足够支撑你搭建第一个 Skill 并跑通示例。

    5.1 安装依赖与环境准备

    在开始之前,先确认环境。推荐使用 Python 3.9 以上的虚拟环境:

    mkdir web-test-skill cd web-test-skill python -m venv venv source venv/bin/activate # Windows 使用 venv\Scripts\activate pip install playwright pytest playwright install chromium

    这里解释一下为什么安装pytest:Skill 本身不关心测试框架,但 pytest 在断言失败时能提供更清晰的报错堆栈,而且 AI 生成的测试用例通常基于 pytest 的断言风格,两者兼容性更好。如果团队已经在用 unittest,也可以替换,但下面的示例以 pytest 写法为准。

    5.2scripts/config.py:统一管理测试配置

    测试配置是自动化测试最容易混乱的地方。环境地址、账号、超时时间等散落在各个脚本里,AI 生成的代码很容易出现“这里一个环境变量、那里一个硬编码”的问题。建议统一收敛到一个配置文件中。

    # 文件路径:web-test-skill/scripts/config.py class TestConfig: BASE_URL = "https://example.com" LOGIN_URL = "/login" DEFAULT_TIMEOUT = 10000 # 毫秒 DEFAULT_USERNAME = "test_user" DEFAULT_PASSWORD = "test_password" SCREENSHOT_DIR = "./screenshots" REPORT_DIR = "./test-reports"

    这是一个最简配置,实际项目中你可能需要从环境变量或配置中心读取。写这个类的好处是:AI 读取 Skill 后,能明确知道测试环境从哪里来,不会在脚本里到处写死 IP 和端口。

    5.3scripts/utils.py:把 Playwright 的常用操作封装成公共方法

    公共方法的目的,不是“为了封装而封装”,而是给 AI 提供固定的动作原语。AI 在进行代码生成时,如果发现 Skill 里已经存在open_pageclick_elementfill_inputtake_screenshot这样的函数,它更倾向于直接调用,而不是从零生成一套可能不稳定的代码。

    # 文件路径:web-test-skill/scripts/utils.py from playwright.sync_api import Page, expect def open_page(page: Page, url: str) -> None: """打开指定 URL,并等待页面加载完成。""" page.goto(url, wait_until="networkidle") def fill_input(page: Page, selector: str, value: str) -> None: """填充输入框,使用原生 fill 方法。""" locator = page.locator(selector) locator.fill(value) def click_element(page: Page, selector: str) -> None: """点击元素,Playwright 会自动等待元素可点击。""" locator = page.locator(selector) locator.click() def assert_text_visible(page: Page, text: str) -> None: """断言页面上出现指定文本。""" expect(page.get_by_text(text)).to_be_visible() def take_screenshot(page: Page, filename: str) -> None: """保存截图,便于排查失败原因。""" page.screenshot(path=f"./screenshots/{filename}", full_page=True) def login(page: Page, username: str, password: str) -> None: """执行登录流程,假设登录表单的 selector 如下。""" open_page(page, "https://example.com/login") fill_input(page, "#username", username) fill_input(page, "#password", password) click_element(page, "#login-btn") assert_text_visible(page, "Dashboard")

    这段代码里有几个值得注意的细节:

    • page.goto使用了wait_until="networkidle",保证页面网络请求基本完成后再继续操作。对于大多数后台管理系统,这个设置比默认的load更稳定。
    • 断言使用expect(...).to_be_visible(),符合 Playwright 的推荐风格。AI 生成代码时,如果我们明确在 Skill 的说明中要求“使用 Playwright 内置断言而不是assert判断元素存在”,脚本的失败信息会友好很多。
    • 所有等待都依赖 Playwright 自动等待,代码里看不到一个sleep,这是刻意设计。

    5.4examples/demo_test.py:一个完整的 pytest 测试用例

    下面给出一个最小但完整的登录测试用例,用于验证 Skill 是否可用。

    # 文件路径:web-test-skill/examples/demo_test.py import pytest from playwright.sync_api import sync_playwright from scripts.config import TestConfig from scripts.utils import login, assert_text_visible, take_screenshot @pytest.fixture(scope="module") def browser_page(): with sync_playwright() as p: browser = p.chromium.launch(headless=True) context = browser.new_context(viewport={"width": 1280, "height": 720}) page = context.new_page() yield page browser.close() def test_login_success(browser_page): """验证正确账号密码可以登录成功。""" page = browser_page login(page, TestConfig.DEFAULT_USERNAME, TestConfig.DEFAULT_PASSWORD) assert_text_visible(page, "Dashboard") def test_login_failed_with_wrong_password(browser_page): """验证错误密码时登录失败,并出现错误提示。""" page = browser_page login(page, TestConfig.DEFAULT_USERNAME, "wrong_password") assert_text_visible(page, "Invalid username or password")

    这个示例里用pytest的 fixture 来管理浏览器生命周期,避免在每个用例里重复写 Playwright 启动代码。对于 Skill 来说,这种写法还有另一个好处:AI 生成的多个测试用例可以直接套用同一个 fixture,而不是每次复制一长串启动代码。

    5.5SKILL.md的完整写法

    为了让 AI 能正确调用上面的脚本,SKILL.md需要写得足够精确。下面是一份可以直接使用的模板:

    --- name: web-test-skill description: Playwright Web 自动化测试 Skill。用于生成登录、订单、页面断言等端到端测试脚本,并指导 AI 使用 scripts/utils.py 中的公共方法。 --- # Web 自动化测试 Skill ## 使用场景 - 针对 Web 页面的端到端自动化测试 - 需要快速生成可运行的 Playwright 测试脚本 - 需要判断测试失败原因并处理 ## 环境要求 - Python 3.9+ - Playwright 1.x - Chromium 浏览器内核 ## 核心规则 1. 优先复用 `scripts/utils.py` 中的函数,不要从零生成浏览器操作代码。 2. 元素定位优先使用 `data-testid`、`id`、`role`,不要使用非常长的 CSS 路径。 3. 禁止使用 `time.sleep()`,等待逻辑统一交给 Playwright 自动等待。 4. 测试数据从 `scripts/config.py` 中读取,不要硬编码账号密码。 5. 每个测试用例结束前,建议调用 `take_screenshot` 保存一张截图。 ## 标准步骤 1. 分析测试需求,确定测试场景。 2. 检查 `scripts/config.py` 中配置是否正确。 3. 编写测试用例,复用 `scripts/utils.py` 中的方法。 4. 使用 `pytest -s examples/demo_test.py` 运行验证。 5. 如果用例失败,检查 `screenshots/` 目录下的截图。 ## 示例代码路径 - `examples/demo_test.py`:登录成功/失败用例 - `examples/quick_start.md`:快速上手文档

    如果你是在 Claude Code、Cursor 或 Codex 中使用这个 Skill,建议把整个目录放在项目根目录下的.agent/skills/web-test-skill/.cursor/skills/等约定位置。不同工具的读取路径不一样,但核心文件结构保持一致就行。

    6. 如何验证 Skill 是否“真的可用”

    很多团队搭建 Skill 后遇到的第一个问题是:AI 虽然能读取 Skill,但生成的测试脚本仍然五花八门。这通常不是模型问题,而是验证方式有问题。

    下面是推荐的验证流程,从“最小可用”逐步到“业务可用”。

    6.1 第一步:让 AI 生成一个最简单的用例

    在已配置 Skill 的 IDE 或命令行工具里,给 AI 输入这样一条指令:

    使用 web-test-skill,生成一个检查首页标题的测试用例。

    预期结果是 AI 生成如下风格代码(或直接读取示例后输出路径):

    def test_homepage_title(browser_page): page = browser_page page.goto("https://example.com") assert page.title() == "Example Domain"

    如果 AI 没有参考 Skill 里的utils.py,而是自己写了一大段 Playwright 代码,说明 Skill 的调用机制没有生效,需要检查 SKILL.md 的description是否被正确索引。

    6.2 第二步:让 AI 生成一个包含登录的用例

    继续输入:

    使用 web-test-skill,生成登录成功后跳转 Dashboard 的用例,并使用 utils 中的 login 方法。

    然后运行:

    cd web-test-skill pytest examples/demo_test.py -s --tb=short

    预期输出:

    collected 2 items examples/demo_test.py::test_login_success PASSED examples/demo_test.py::test_login_failed_with_wrong_password PASSED

    如果测试失败,优先查看screenshots/目录下的截图。截图能直观反映页面当时的状态,比看一堆 DOM 报错更高效。

    6.3 第三步:检查 AI 输出的代码是否遵守约定

    这一步容易被忽略。有时测试通过了,但代码质量并不符合团队规范。关键检查项包括:

    • 有没有使用time.sleep()
    • 有没有硬编码 URL 和账号密码;
    • 有没有直接使用.click()而不是.click(force=True)(后者通常意味着定位器有问题);
    • 有没有在测试结束后关闭浏览器上下文;
    • 有没有输出清晰的中文或英文步骤说明。

    如果 AI 生成的代码不满足这些要求,不要立刻责怪 AI,而是检查SKILL.md的规则写得更明确。Skill 本质上像面向 AI 的编码规范,越是把规则写进文件,输出质量越稳定。

    7. 常见问题与排查思路

    问题现象可能原因排查方式解决方案
    AI 不读取 Skill 直接生成代码SKILL.md 的 description 不匹配当前任务查看工具日志里 Skill 是否被加载将 description 改成更贴合实际任务的描述,比如“Web 自动化测试生成与执行”
    脚本运行报locator.click()超时页面元素被遮挡或需要滚动到可见区域查看截图确认元素状态改用scroll_into_view_if_needed()或使用role定位
    测试登录时一直失败,但手动操作正常验证码、动态 Token 或前端加密干扰抓取点击登录按钮时的网络请求在测试环境禁用验证码,或把动态数据用测试接口 mock
    AI 生成的代码总用time.sleep()Skill 中没有明确禁用规则检查 SKILL.md 是否写明禁止time.sleep在规则里增加“等待统一交给 Playwright 自动等待”
    测试用例依赖执行顺序,单独运行就失败用例之间有状态依赖用 pytest 的--pdb定位失败点拆分用例,每条用例独立建 context
    多浏览器跑测试时 webkit 失败WebKit 内核环境未安装运行playwright install webkit先统一只在 chromium 上跑,稳定后再扩充

    这里特别想强调表格里第二行的问题。很多初学者遇到click超时就直接加time.sleep(5),这会让问题更隐蔽。正确做法是先截图,看元素是否在视口中、是否被弹窗遮挡。Playwright 的定位器已经包含自动滚动和等待机制,如果仍然超时,大概率是页面本身有异常,而不是等待时间不够。

    8. Skill 落地到团队的最佳实践

    8.1 不要追求“一个 Skill 覆盖所有测试场景”

    测试团队最常见的一个误区,是试图把接口测试、UI 测试、性能测试全塞进一个 Skill 里。这样做的结果往往是 SKILL.md 越来越长,AI 的选择越来越混乱。

    建议按场景拆成多个 Skill:

    • web-ui-test-skill:负责端到端 UI 测试;
    • api-test-skill:负责接口自动化测试;
    • test-data-gen-skill:负责测试数据生成。

    每个 Skill 只做好一件事。AI Agent 会根据任务描述自动选择合适的 Skill,这比让一个超大 Skill 强行处理所有场景可靠得多。

    8.2 SKILL.md 要版本化,并纳入 Code Review

    Skill 的更新会影响所有 AI 生成的代码,因此应该像普通源码一样管理。团队里最好是测试架构师或资深测试开发负责维护 Skill 文件,每次改动都要说明“为什么改”。比如新增了一条“禁止在断言中使用模糊文本”的规则,就应该在 Commit Message 里写清楚:是因为某个用例误判了页面上的两处相似文本,才加这条约束。

    8.3 用示例代码而不是描述来约束 AI

    AI 对示例代码的模仿能力远强于对抽象规则的理解。如果你的团队希望所有测试脚本都使用>

http://www.cnnetsun.cn/news/4295754.html

相关文章:

  • Python与PyCharm安装全攻略:从环境变量到第一个项目运行
  • 腾讯2015春招移动客户端开发面试题核心考点解析
  • 从投递到拿offer:BAT实习面试全流程实战指南
  • 第04章 C类型、运算符和表达式(2):揭示内存背后的秘密——变量名、常量与声明的本质
  • 扫描Git仓库中的LLM推理痕迹:构建Aileaks类安全扫描器
  • python的图论工业场景模拟第十四篇:基于NetworkX与Matplolib图可视化模板构建,任务:设计并封装一个统一风格的画图函数,节点颜色映射度数,边粗细映射权重,避免标签重叠,图建模说明:确
  • 温州市本地维修壁挂炉师傅|上门维修壁挂炉电话|故障码不点火维修|本地口碑维修推荐
  • STM32WB55 SafeBoot烧录报错排查:RDP写保护与解锁实战
  • STM32U5并口屏驱动实战:FMC与GPDMA 2D寻址方案解析
  • 从OTAmatic获奖看车载OTA平台架构与工程实践要点
  • 基于Seq2Seq模型的Web攻击检测系统:从NLP到AI安全的工程实践
  • 传感器接口IC如何攻克生物化学传感的微弱信号难题?
  • 混合RL Rollout调度:超越Prefix Locality的推理优化实践
  • 产品岗笔试通关指南:题型拆解、答题框架与时间分配全攻略
  • LLM输出随机性解析:温度、种子与垂直AI稳定性实践
  • 解析pro文件
  • 一个 关于 椒盐 的 笑话
  • 基于pandas apply的文本预处理函数设计与DataFrame应用实践
  • C++模板与泛型编程:从《C++ Primer》习题解析到工业级代码实践
  • 手把手搭建反AI电脑:本地优先与数据隐私实践
  • 网易校招研发笔试复盘:数据结构与算法考点全解析
  • 百度前端秋招笔试复盘:从JS原理到算法题型的备考指南
  • Python数据分析与建模实战:从美赛C题到完整项目工作流
  • 阿里云秋招笔试深度拆解:从基础到云原生的备考指南
  • 阿里云研发岗秋招笔试复盘:从算法到工程实战的全面解析
  • STM32 MotionGR手势识别库:从配置到移植的完整实战指南
  • select为什么只能处理1024个连接?从源码到排障彻底讲透
  • 全国地貌shp矢量数据实操指南:从加载到转换全解析
  • C++26 std::hive 性能实测:稳定句柄与缓存局部性优势
  • 2018用友前端笔试题拆解:手写EventEmitter背后的JS核心机制