尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

Pytest+Skills+MCP:AI驱动Web自动化测试实战指南

Pytest+Skills+MCP:AI驱动Web自动化测试实战指南 90分钟PytestSkillsMCP自动化AI玩转WEB自动化只讲干货很多人以为 AI 自动化测试就是让 ChatGPT 直接生成一段 Pytest 脚本然后复制粘贴到项目里跑一遍。这个思路没有错但只完成了“AI 写代码”这一步离真正的“AI 玩转 Web 自动化”还差得很远。因为 AI 生成脚本只是替你把键盘敲了脚本运行过程中的浏览器控制、页面元素定位、断言校验、失败重试依然依赖你手里的测试框架和自动化工具。换句话说AI 负责“思考”但“手脚”还得靠工具链来提供。MCP 的出现改变了这个格局。当我们讨论 MCP 自动化时其实是在讨论一个问题如何让大模型直接操控浏览器像一个测试工程师那样自己观察页面、执行操作、判断结果而不是只输出一段代码让人类去跑。这篇文章聚焦 Pytest Skills MCP 的组合玩法不讲空洞概念直接告诉你这条链路里每个环节是干什么的、怎么接起来、会遇到什么坑。如果你是测试开发、自动化测试工程师或者正在研究 AI Agent 如何落地到 Web 场景这篇文章值得看完并收藏备用。1. 这篇文章真正要解决的问题先给一个结论AI 不会取代 Web 测试但会重构测试脚本的生产方式。过去写 Web 自动化测试你大概率经历过这样的流程打开浏览器开发者工具复制 XPath 或 CSS 选择器写定位逻辑加显式等待处理弹窗跑一次失败再调试。一个简单的登录用例写 30 到 50 行 Pytest 代码是常态。如果页面改版选择器大量失效维护成本比编写成本还要高。AI 参与之后很多人以为痛点消失了。但实际用过就会发现让 AI 生成一段 Selenium 脚本非常简单可这段脚本能不能稳定运行、能不能处理动态页面、能不能在 CI 里持续跑是另一回事。AI 模型的优势是语义理解弱项是环境感知和工具调用。它不知道当前浏览器打开了哪个页面不知道哪些元素可见不知道网络请求是否完成。这正是 MCPModel Context Protocol要解决的问题。MCP 给 AI 提供了一条标准化的“工具调用通道”。通过 MCP ServerAI 可以读取页面状态、执行点击输入、获取 DOM 信息、判断断言结果。Pytest 则负责把整个流程组织成结构化的测试用例生成测试报告接入 CI/CD 流水线。所以这篇文章的核心线索只有一条如何围绕 Pytest 搭一条“AI 可调用浏览器”的自动化链路让 AI 不只写脚本而是直接干活的测试执行者。2. 基础概念与核心原理2.1 Pytest 在 AI 自动化中的真实定位Pytest 是 Python 生态最主流的测试框架很多自动化测试项目都用它来组织用例、管理夹具Fixture、执行断言、生成报告。在传统自动化测试中Pytest 是核心骨架用例结构、夹具、参数化、插件都是围绕 Pytest 组织。在 AI 自动化链路中Pytest 的角色依然不可替代它负责定义测试用例的结构、控制用例的执行顺序、管理浏览器实例的生命周期、执行断言并输出报告。你可以这样理解AI 是“临时工”根据自然语言描述去操作浏览器Pytest 是“正式编制”负责验收临时工的工作结果并保证整个过程可复现、可追溯、可集成。2.2 MCP 到底是什么MCP 是 Model Context Protocol 的缩写即模型上下文协议。它定义了一套标准接口让 AI 模型能够调用外部工具和数据源。很多人初次接触 MCP 时容易把它理解成一个具体软件或框架。实际上它是一套通信协议类似 HTTP 对于 Web 通信的意义。通过 MCPAI 客户端例如 Claude Desktop、Cursor、Codex 等可以连接多个 MCP Server每个 Server 提供若干 Tool工具。AI 模型在对话中决定调用哪个工具、传入什么参数然后拿到工具返回的结果继续推理。在 Web 自动化场景中MCP Server 可以暴露以下工具open_page打开指定 URL。click_element点击页面上的指定元素。fill_input向输入框填充文本。get_page_text读取当前页面文本。assert_element_visible断言元素是否可见。AI 不直接写 Selenium 脚本而是通过 MCP 协议调用这些工具像人一样操作浏览器。这个模式的本质变化是测试逻辑从“代码编写”变成了“意图表达 工具调用”。2.3 Skills 和 MCP 有什么区别最近很多 AI 编程工具开始同时支持 MCP 和 Skills容易混淆。简单对比对比项MCPSkills核心作用让 AI 调用外部工具和数据源让 AI 复用预先定义的经验和技能模板解决什么问题模型缺少操作外部环境的能力模型缺少领域经验和操作套路类比USB 接口插上就能用岗位手册按手册干活在 Web 自动化的作用连接浏览器自动化工具封装测试操作套路例如“登录步骤”“分页遍历规则”在实际链路中Skills 和 MCP 往往配合使用。Skills 定义“遇到登录页面应该怎么操作、等待时应该关注什么”MCP 提供“实际点击、输入、读取页面”的执行能力。对测试团队来说Skills 是沉淀业务经验的好载体。3. 环境准备与前置条件在开始实践之前需要把基础环境准备好。本文涉及的版本信息以你实际安装时为准重点演示通用思路。3.1 基础运行环境操作系统Windows / macOS / Linux 均可本文命令以 Linux/macOS 为示例Windows 用户注意路径差异。Python建议 3.10 或以上版本可以通过python --version确认。浏览器建议安装 Chrome 或 Chromium便于自动化调试。3.2 安装 Python 依赖建议先创建虚拟环境避免依赖污染系统 Python。下面的命令使用venvmkdir ai-web-automation cd ai-web-automation python -m venv venv source venv/bin/activate # Windows 下使用 venv\Scripts\activate然后安装核心依赖pip install pytest pip install pytest-playwright pip install playwright playwright install chromium如果你要用 MCP Server 方式暴露浏览器工具还需要安装 MCP SDK。常用的安装方式pip install mcp不同 AI 客户端可能要求不同规格的 MCP Server建议以官方文档为准。下面演示基于mcpPython SDK 的通用实现。3.3 验证环境是否就绪安装完成后先写一个最简单的 Pytest 用例验证环境# 文件路径test_env.py def test_environment_ready(): assert True运行pytest -v test_env.py看到测试通过说明 Pytest 环境正常。接下来再验证 Playwright 能否启动浏览器# 文件路径test_browser.py from playwright.sync_api import sync_playwright def test_launch_browser(): with sync_playwright() as p: browser p.chromium.launch(headlessTrue) page browser.new_page() page.goto(about:blank) assert page.title() browser.close()运行方式同上如果浏览器成功启动并打开空白页说明 Playwright 基础可用。4. 核心流程拆解从自然语言需求到可运行的 AI 自动化测试整个流程可以拆成五个关键环节。4.1 环节一定义目标场景首先明确你想让 AI 完成什么操作。以最常见的登录场景为例打开 https://example.com/login输入用户名输入密码点击登录按钮断言登录成功后页面上出现“欢迎”字样这一步的价值在于把模糊需求转成可验证的步骤。AI 再聪明也需要明确的目标和验收标准。4.2 环节二用 Pytest 搭建用例骨架Pytest 负责整体节奏。通过 Fixture 管理浏览器实例可以减少重复代码并且保证每个测试用例运行前后浏览器状态干净。# 文件路径conftest.py import pytest from playwright.sync_api import sync_playwright pytest.fixture(scopesession) def browser_context(): with sync_playwright() as p: browser p.chromium.launch(headlessTrue) context browser.new_context() yield context browser.close() pytest.fixture def page(browser_context): page browser_context.new_page() yield page page.close()4.3 环节三将浏览器能力暴露给 AI这是整条链路最关键的一环。为了让 AI 能调用浏览器我们需要实现一个 MCP Server把浏览器操作封装成一个个 Tool。# 文件路径browser_mcp_server.py from mcp.server import Server from mcp.server.stdio import stdio_server from playwright.sync_api import sync_playwright import json app Server(browser-mcp-server) playwright sync_playwright().start() browser playwright.chromium.launch(headlessTrue) app.tool() def open_page(url: str) - str: 打开指定 URL并返回页面标题 page browser.new_page() page.goto(url) return json.dumps({title: page.title()}) app.tool() def fill_input(page_id: str, selector: str, value: str) - str: 向指定选择器对应的输入框填入文本 page browser.contexts[0].pages[int(page_id)] page.fill(selector, value) return json.dumps({status: filled}) # 其他工具类似 def main(): stdio_server.run(app) if __name__ __main__: main()注意上面是结构示意不同版本的 MCP SDK API 有差异实际开发时以官方文档为准。生产环境中建议将浏览器实例做更细粒度的生命周期管理避免资源泄漏。4.4 环节四让 AI 基于任务调用工具配置好 MCP Server 后在 AI 客户端中启用该 Server。然后给出一段自然语言指令打开 https://example.com/login在 #username 输入 admin在 #password 输入 123456点击 #login-btn然后读取页面文本判断是否包含“欢迎”两个字。AI 会根据指令依次调用 MCP Server 暴露的工具完成浏览器操作并返回执行结果。4.5 环节五在 Pytest 中做最终断言AI 执行完并不代表测试通过。最终验收应该由 Pytest 完成# 文件路径test_ai_login.py from playwright.sync_api import sync_playwright def test_login_with_ai_execution(): with sync_playwright() as p: browser p.chromium.launch(headlessTrue) page browser.new_page() page.goto(https://example.com/login) page.fill(#username, admin) page.fill(#password, 123456) page.click(#login-btn) page.wait_for_load_state(networkidle) assert 欢迎 in page.text_content(body) browser.close()这一步的意义在于无论 AI 多么智能最终的测试结论必须落到可校验的断言语义上。5. 完整示例代码实现为了让链路更清晰下面给出一个相对完整的项目示例。你可以照着创建文件跑通最小验证。5.1 项目结构ai-web-automation/ ├── conftest.py ├── test_login.py ├── browser_mcp_server.py ├── skills/ │ └── login_skill.yaml └── requirements.txt5.2 requirements.txtpytest7.4.0 pytest-playwright0.4.3 playwright1.40.0 mcp0.1.0注意版本号请以实际环境为准必要时直接去掉版本号安装最新版。5.3 conftest.py# 文件路径conftest.py import pytest from playwright.sync_api import sync_playwright pytest.fixture(scopesession) def browser(): with sync_playwright() as p: browser p.chromium.launch(headlessTrue) yield browser browser.close() pytest.fixture def page(browser): page browser.new_page() yield page page.close()5.4 test_login.py# 文件路径test_login.py def test_login_success(page): # 打开登录页 page.goto(https://example.com/login) # 输入账号密码 page.fill(#username, admin) page.fill(#password, 123456) # 点击登录按钮 page.click(#login-btn) # 等待页面加载完成 page.wait_for_load_state(networkidle) # 断言登录成功 body_text page.text_content(body) assert 欢迎 in body_text, f登录后页面未出现欢迎信息实际内容{body_text} def test_login_failed_wrong_password(page): page.goto(https://example.com/login) page.fill(#username, admin) page.fill(#password, wrong-password) page.click(#login-btn) page.wait_for_load_state(networkidle) error_text page.text_content(.error-message) assert 密码错误 in error_text5.5 browser_mcp_server.py这里给出一个更完整的 MCP Server 示例。需要注意MCP SDK 的 API 还在快速演进下面代码偏向思路展示实际接入请查阅你使用的 SDK 版本。# 文件路径browser_mcp_server.py 将 Playwright 浏览器能力封装成 MCP 工具。 运行方式python browser_mcp_server.py import json from mcp.server import Server, stdio_server from playwright.sync_api import sync_playwright app Server(web-automation-server) pw sync_playwright().start() browser pw.chromium.launch(headlessTrue) pages [] app.tool() def browser_open_page(url: str) - str: 打开网页返回页面标题和 URL page browser.new_page() page.goto(url, wait_untilnetworkidle) pages.append(page) return json.dumps({title: page.title(), url: page.url}) app.tool() def browser_fill(selector: str, value: str) - str: 向当前页面的选择器对应元素填充文本 if not pages: return json.dumps({error: 没有打开的页面}) page pages[-1] page.fill(selector, value) return json.dumps({status: filled, selector: selector}) app.tool() def browser_click(selector: str) - str: 点击当前页面的某个元素 if not pages: return json.dumps({error: 没有打开的页面}) page pages[-1] page.click(selector) page.wait_for_load_state(networkidle) return json.dumps({status: clicked, selector: selector}) app.tool() def browser_get_text() - str: 获取当前页面 body 文本 if not pages: return json.dumps({error: 没有打开的页面}) page pages[-1] text page.text_content(body) return json.dumps({text: text}) def main(): stdio_server.run(app) if __name__ __main__: main()5.6 skills/login_skill.yamlSkills 用于沉淀操作经验。以下是一个简单的登录技能大纲name: login_skill description: 执行登录流程包含账号密码输入、登录按钮点击和结果校验。 steps: - open_page: ${base_url}/login - wait_for_selector: #username - fill_selector: selector: #username value: ${username} - fill_selector: selector: #password value: ${password} - click_selector: #login-btn - wait_for_load_state: networkidle - assert_text_contains: selector: body expected: 欢迎这个 YAML 本身不能直接执行它的作用是给 AI 提供操作模板。AI 在工作时先读取 Skill 内容再决定如何调用 MCP 工具。这是 Skills 与 MCP 协同工作的典型场景。5.7 运行与验证依次启动 MCP Server然后在你的 AI 客户端中连接这个 Server。输入自然语言指令后观察 AI 是否按预期调用工具。与此同时在另一个终端运行 Pytest 用例pytest -v预期结果test_login.py::test_login_success PASSED test_login.py::test_login_failed_wrong_password PASSED如果页面元素、选择器等与示例不一致需要根据实际站点修改测试脚本。6. 运行结果与效果验证判断这套链路是否真正跑通不能只看 AI 有没有执行操作还要从以下三个维度验证6.1 功能维度AI 是否能成功打开目标页面AI 是否能定位到输入框并填入正确内容AI 是否能点击登录按钮AI 是否能读取页面文本并给出判断这些可以通过 MCP Server 的日志确认。每次工具调用都会记录入参和返回值检查日志即可。6.2 测试框架维度Pytest 用例是否全部通过用例失败时断言信息是否足够定位问题失败截图、页面 HTML 是否被保留建议在 Fixture 中加入失败截图逻辑# 文件路径conftest.py import pytest from playwright.sync_api import sync_playwright pytest.fixture def page(browser): page browser.new_page() yield page page.close() pytest.hookimpl(tryfirstTrue, hookwrapperTrue) def pytest_runtest_makereport(item, call): outcome yield report outcome.get_result() if report.when call and report.failed: page item.funcargs.get(page) if page: screenshot page.screenshot() with open(ffailure_{item.name}.png, wb) as f: f.write(screenshot)6.3 稳定性维度AI 执行操作时最怕的是步骤顺序错乱或时序问题。验证稳定性时可以连续运行用例pytest -v --count 5如果多次运行存在偶发失败优先检查等待条件是否充分。AI 工具调用之间也需要设置合理的等待和超时策略。7. 常见问题与排查思路在实际落地过程中这套链路最常见的问题往往不在 AI 模型本身而在工程细节。下面整理一个排查表问题现象可能原因排查方式解决方案Pytest 运行后找不到用例文件名不是test_*.py或*_test.py格式检查目录下文件命名按 Pytest 规范重命名浏览器报错 Executable doesnt existPlaywright 浏览器未安装执行playwright install chromium安装对应浏览器内核元素定位失败 TimeoutError页面加载慢、选择器失效查看 Playwright 日志和页面截图增加等待时间改用更稳定的选择器MCP Server 无法启动SDK 版本不兼容检查 Python 环境依赖版本升级或降级 MCP SDK 版本AI 不会调用工具Server 未被正确配置或工具定义不清在 AI 客户端中测试连接检查 Server 地址和工具描述优先使用明确的 tool 名称和 description断言不稳定偶发失败页面异步加载导致文本未出现打印实际页面文本使用显式等待代替固定 sleep失败没有截图未添加失败 hook查看 conftest.py 中 hook 是否生效在pytest_runtest_makereport中添加截图逻辑排查时记住一个原则先看工具层再看框架层最后才怀疑 AI 模型。多数问题出在浏览器驱动、选择器稳定性或时序等待上而不是模型理解能力。8. 最佳实践与工程建议8.1 用 Skills 沉淀业务经验测试团队最宝贵的资产不是脚本代码而是对业务的理解。把常见操作套路沉淀为 Skills例如“登录流程”“分页查询流程”“表单提交流程”AI 在执行相似任务时可以直接复用这些经验模板减少重复试错成本。8.2 AI 操作必须加超时和重试机制AI 调用工具时如果页面长时间未加载或元素未出现工具可能长时间阻塞。建议每个 MCP 工具内部都加入超时控制。Playwright 本身支持超时参数例如page.fill(#username, admin, timeout5000) # 5秒超时 page.click(#login-btn, timeout5000)8.3 选择器优先级从数据属性到语义化给 AI 提供稳定的选择器是提高成功率的关键。优先使用>
返回列表