Pytest+MCP+AI实现Web自动化:从环境搭建到批量执行
先说结论Pytest MCP AI 这套组合最近在 WEB 自动化圈子里讨论度很高但真正能落地到日常测试项目的其实不多。大多数人卡在同一个地方AI 能聊天、能给你建议、也能生成一段用例代码但要让 AI 自己打开浏览器、填表单、点按钮、断言页面结果中间还隔着 MCP 这一层协议。这篇文章把一条 90 分钟能走完的学习路径拆给你先弄懂 Pytest、MCP、Skills 各自解决什么问题然后从最小用例开始一步步跑到批量 WEB 自动化测试。适合谁看已经会 Python 基础写过普通测试脚本但还没接触过 MCP 的人最合适。最值得关注的点是把 AI 当成测试执行器而不是只会生成代码的工具。AI 不再只是帮你写用例而是直接通过 MCP 调用浏览器工具按你的要求去操作页面再把结果交回 Pytest 做断言。这个思路一旦跑通很多重复的冒烟测试、回归检查都能提速。下面按一条完整的学习路径来写从环境准备到批量执行再到排查问题尽量把每一步的判断标准说清楚。1. 先搞清楚 Pytest、MCP、Skills 在 WEB 自动化里各自管什么很多人一上来就把这三个概念混在一起导致后面配置混乱、报错看不懂。其实它们的分工非常清楚Pytest 是测试框架MCP 是 AI 和工具之间的通信协议Skills 是 AI 行为的封装单元。1.1 Pytest 负责组织测试不负责替 AI 做决定Pytest 在传统 WEB 自动化里已经非常成熟。它的职责是收集用例、按顺序执行、记录结果、抛出断言失败。你可以用 fixture 管理浏览器实例用 parametrize 做数据驱动用插件生成报告。在 AI 驱动的自动化里Pytest 的职责没有变仍然负责整个测试生命周期。AI 只是测试过程中的一个执行节点。换句话说Pytest 是总管AI 是干活的执行者浏览器是 AI 手里的工具。不要指望 Pytest 替你处理 AI 的输出。AI 返回的是自然语言或结构化结果Pytest 需要负责把结果转成断言条件或者直接从 AI 的回应里提取关键字段做校验。1.2 MCP 是 AI 和浏览器工具之间的桥梁MCP 的全称是 Model Context Protocol解决的问题是让 AI 模型能够标准化地调用外部工具和数据源。你可以把它理解为一种统一的“插头协议”AI 通过 MCP 连接不同的服务比如文件系统、数据库、浏览器控制工具。在 WEB 自动化场景中最常用的 MCP 服务是浏览器控制类服务。社区里已经有 Playwright MCP 这类成熟方案它把打开页面、点击元素、输入文本、截图、取页面内容这些动作暴露给 AI。AI 只需要按工具定义的参数调用不需要知道底层是用 Selenium 还是 Playwright。这里要注意一点MCP 更像是一个协议规范不是某个特定软件。你可以用官方 SDK 写自己的 MCP server也可以直接使用社区做好的通用服务。学习阶段建议先用现成的浏览器 MCP跑通之后再考虑定制。1.3 Skills 是把 AI 的“动作套路”固定下来Skills 是最近 AI Agent 领域常说的概念。它本质上是一份结构化的“操作说明书”告诉 AI在什么场景下、按什么步骤、调用哪些工具、遵守什么约束。举一个例子。你要让 AI 执行“登录并检查购物车数量”这个任务。如果没有 Skill你需要每次在 Prompt 里详细描述步骤AI 很容易在过程中出现偏差。如果有了 Skill你只需要把 Skill 的内容挂载到当前会话里AI 会自动按规则执行。Skills 和 MCP 的区别在于MCP 是管道Skills 是管道里的作业指导书。MCP 决定 AI 能不能调用工具Skills 决定 AI 怎么调用工具。两者配合才能让 AI 在测试任务里稳定输出。2. 90 分钟学习路线怎么拆环境、工具链、最小样例我建议把 90 分钟拆成三块15 分钟准备环境30 分钟跑通 Pytest 浏览器驱动的普通用例45 分钟接入 MCP 和一条 AI 调用用例。不要一上来就把所有东西都搭好再跑那样出了问题很难定位。2.1 环境准备Python、依赖、浏览器驱动先说基本条件。操作系统方面Windows、macOS、Linux 都能跑但要注意浏览器驱动是否匹配。Python 版本建议 3.10 以上因为很多 MCP 相关的 SDK 和 AI 客户端库开始收紧版本要求了。需要安装的基础依赖包括pip install pytest playwright安装完成后还要执行一次浏览器的下载安装命令playwright install chromium这一步如果跳过后面运行用例会报浏览器可执行文件找不到的错误。常见浏览器里Chromium 是兼容性最好的选择建议先用它。如果你要用 Playwright MCP还需要安装对应的 MCP 服务包。不同 SDK 的包名不一样建议先确认你使用的 AI 客户端和 MCP SDK 文档。这里给的是通用思路不要照抄命令。2.2 先跑通一个普通 Pytest 用例再谈 AI这一阶段的目标是确认 Pytest、Playwright、浏览器驱动三者能正常工作。写一个最简单的用例打开百度首页断言标题包含“百度”。from playwright.sync_api import sync_playwright def test_open_baidu(): with sync_playwright() as p: browser p.chromium.launch(headlessTrue) page browser.new_page() page.goto(https://www.baidu.com) assert 百度 in page.title() browser.close()运行命令pytest test_demo.py -v如果这条用例通过了说明你的基础链路没问题。如果失败优先检查浏览器驱动、网络访问权限、页面是否被反爬拦截。这一阶段不要引入 AI避免问题叠加。2.3 接入 MCP让 AI 能调用浏览器动作接入 MCP 的常见方式是使用支持 MCP 的 AI 客户端工具比如 Cursor、Trae 或者其他支持 MCP server 的编程助手。也有一些场景是直接写一个 MCP server在命令行里通过 AI 客户端连接。以通用结构为例一个浏览器 MCP server 的配置大约如下{ mcpServers: { web-automation: { command: python, args: [path/to/mcp_server.py], env: {} } } }上面的结构只是一个示意。实际配置时你需要确认 AI 客户端支持哪种 MCP 配置格式是.mcp.json文件还是claude_desktop_config.json还是应用内的设置界面。配置完成后下一步就是验证 AI 是否真的能通过 MCP 控制浏览器。你可以直接在 AI 对话里输入“用浏览器工具打开百度然后告诉我页面标题是什么”。如果 AI 正确调用工具并返回标题说明 MCP 链路已经通了。这个环节最容易出现的问题包括MCP server 没有正确启动、工具注册不上、浏览器驱动路径不对、或者 AI 客户端没有重新加载配置。遇到这类问题先看 MCP server 的启动日志再确认工具列表里是否出现了open_page之类的工具。3. 把 AI 能力封装成可复用的 Skill而不是每次写 Prompt跑通一条 AI 用例之后你会产生一个冲动把所有测试步骤全写进一个巨大的 Prompt让 AI 一把梭。我劝你不要这样做。AI 对长 Prompt 的理解会漂移一旦中间某一步出错它会自行“发挥”结果很难复盘。正确的做法是封装 Skill。3.1 Skill 的本质提示词加工具约束一个 Skill 通常包含三部分内容适用场景描述、执行步骤、调用工具列表。场景描述用来告诉 AI 什么时候该用这个 Skill执行步骤用来规定动作顺序调用工具列表用来限制 AI 能做什么。以“登录并检查购物车”为例一个 Skill 大致是这样的# LoginAndCheckCart Skill 适用场景用户需要验证登录流程并确认购物车数量是否正确。 执行步骤 1. 使用 open_page 工具打开登录页面。 2. 使用 fill_form 工具填写用户名和密码。 3. 使用 click_element 工具点击登录按钮。 4. 等待页面跳转完成。 5. 使用 get_text 工具获取购物车数量元素。 6. 将最终数量以 JSON 格式返回给用户。 约束 - 不要点击任何无关元素。 - 失败时返回错误信息不要重试超过两次。 - 不访问登录页面之外的网址。这份 Skill 本身不是程序而是 AI 对话中的系统指令。你把它的内容挂载到 AI 会话里AI 就会按照这个套路执行。这样做的最大好处是稳定同样一个任务无论谁发起AI 的思考路径都一致。3.2 用 Pytest fixture 管理 AI 会话和浏览器实例在 Pytest 中fixture 是用来管理前置状态和清理工作的重要机制。你可以把 AI 客户端的初始化、浏览器的创建和关闭都放到 fixture 里这样每条用例都能复用同一个环境。import pytest from playwright.sync_api import sync_playwright pytest.fixture def browser_page(): with sync_playwright() as p: browser p.chromium.launch(headlessTrue) page browser.new_page() yield page browser.close() pytest.fixture def ai_client(): # 这里初始化一个 AI 客户端连接 MCP server # 具体实现依赖你使用的 AI SDK client create_ai_client() yield client client.disconnect()上面的create_ai_client是示意函数真实实现要依赖你选择的具体客户端库。关键是思路把 AI 连接和浏览器实例作为资源交给 fixture 管理避免每条用例都重复启动连接。这种设计不仅能减少资源开销还能在用例之间共享浏览器上下文比如登录状态、Cookie 缓存。对于回归测试场景能明显加快执行速度。3.3 从 Skill 到 Pytest 断言AI 是步骤不是答案AI 执行完网页操作后返回给 Pytest 的是一段结构化或半结构化结果。Pytest 要做的是解读这个结果再决定测试是通过还是失败。一个比较好的实践是让 AI 始终返回固定格式 JSON比如{ status: success, cart_count: 3, message: 登录成功购物车数量已获取 }然后在 Pytest 断言里解析这个 JSONdef test_login_and_cart(ai_client, browser_page): result ai_client.execute_skill(LoginAndCheckCart) assert result[cart_count] 2, 购物车数量不应少于2这里最关键的原则不要让 AI 自己断言结果。AI 只负责执行操作和返回事实是否通过测试由 Pytest 的业务逻辑来决定。这样即使 AI 判断错误Pytest 的失败信息也能准确反映。4. 从单条用例到批量 WEB 测试参数化、数据驱动、失败重试单条 AI 用例跑通后你已经理解了整条链路。但测试工作的现实是你需要跑几十条用例覆盖不同账号、不同商品、不同入口。这时候如果还是一条一条写用例效率会非常低。下面这套组合可以解决批量问题。4.1 参数化用例设计用一条用例覆盖多组输入Pytest 的parametrize是批量测试的基石。你可以把多个测试场景的参数化为列表让同一条用例执行多次。pytest.mark.parametrize(username,password,expected, [ (user01, pass01, 登录成功), (user02, wrong_pass, 密码错误), (, pass03, 用户名为空), ]) def test_login(username, password, expected, ai_client): result ai_client.execute_skill( LoginSkill, inputs{username: username, password: password} ) assert result[message] expected这种写法的好处是测试数据从业务逻辑中分离出来。数据可以放到 CSV、JSON 或数据库里用 pytest 的钩子或第三方库读取。对于 WEB 自动化测试通常参数包括 URL、用户输入、期望结果、等待时间等。需要注意AI 执行参数化用例时每一条都会独立调用 MCP 工具。如果参数差异很大比如切换不同站点建议把站点 URL 也放进参数里避免 AI 沿用上一条用例的上下文。4.2 失败重试和日志收集批量任务必须有这个机制批量执行时AI 调用 MCP 工具可能偶尔失败比如页面加载超时、元素被遮挡、网络抖动。这些不能一票否决需要使用失败重试策略。在 Pytest 体系中可以给用例添加重试标记pytest.mark.flaky(reruns2, reruns_delay1) def test_purchase_flow(ai_client): ...上面的标记依赖pytest-rerunfailures插件。安装后用例失败会按设定次数重试。这个功能在 AI 驱动的测试里尤其重要因为 AI 工具调用的噪声比传统脚本高很多。日志收集同样重要。建议在 fixture 中把 AI 客户端的完整请求和响应记录到日志文件不仅记录最终结果还要记录每次工具调用的参数和返回值。这样如果批量跑完后有 3 条用例失败你能从日志里回溯出 AI 在哪里做出了错误决策。4.3 并发执行时的资源控制不要一上来就拉满并发批量用例多了之后自然会想到用pytest-xdist做并发执行。但并发模式在 AI 测试里有特殊风险AI 客户端连接、浏览器实例、MCP server 都可能不是线程安全的。建议按这个顺序逐步调大并发先用单进程跑完 20 条用例记录单条平均耗时。再用 2 个并发跑同样的用例观察是否有资源冲突。确认稳定后再尝试 4 到 8 个并发。如果某个过程中出现浏览器崩溃、AI 连接断开、MCP server 拒绝服务先不要继续调大。检查是否每个 worker 都独立初始化了浏览器和 AI 客户端。共享状态往往是并发的头号敌人。5. 排查链路与常见坑先看日志再改参数这部分是我自己踩过最多坑的地方。很多人一遇到报错就开始猜这里改一句代码那里试一个参数结果越改越乱。正确的排查逻辑应该是分层进行的。5.1 先看现象分类不要直接改代码我把常见的报错现象分成四个类型现象可能原因排查动作MCP 工具调用失败MCP server 未启动、工具未注册、配置错误查看 MCP server 日志确认工具列表浏览器打不开页面浏览器驱动缺失、路径错误、网络被限制单独运行 Playwright 打开页面测试AI 返回内容不符合格式Prompt 约束不够、Skill 描述不清晰检查 Skill 定义和返回结构Pytest 用例断言失败页面结构变化、期望值不正确查看失败时页面的截图或 HTML 内容根据现象先判断属于哪个层面再打开对应层面的日志。不要跳过日志直接改参数尤其是不要一上来就调大超时时间那样只会掩盖问题。5.2 关于超时和重试默认值够用先别动AI 通过 MCP 调用浏览器工具时最常发生的错误是“执行超时”。默认超时一般在 10 到 30 秒之间但如果页面加载慢这个时间可能不够。我的建议是先区分是单次工具调用超时还是整个用例超时。单次工具调用超时可能影响单条用例整个用例超时往往是因为 AI 在某个环节陷入了死循环。更合理的做法是把超时时间设置成正常耗时的两到三倍。比如正常情况下打开一个商品详情页需要 6 秒你可以把工具的timeout参数设为 15 秒。不要设置成无限超时因为 AI 卡住时无限等待会让你完全失去控制。5.3 资源占用检查显存、内存、磁盘空间如果你的 AI 模型是本地部署的比如通过本地大模型接入 MCP那资源占用就是一个必须关注的维度。显存本地大模型推理时显存需求通常在 6GB 到 40GB 不等。跑测试任务时模型推理和浏览器渲染会同时占用显存低配机器容易报显存不足。内存浏览器本身是内存大户Playwright 也会占内存。批量并发时要监控系统内存使用率。磁盘空间浏览器缓存、测试截图、AI 对话日志都可能快速增长。长时间跑批量任务磁盘写入量比你想象中要多。如果发现资源占用濒临上限不要继续加并发。先把 headless 模式打开再把截图的存储频率降低或者增加日志轮转。5.4 几个容易误判的坑第一个坑AI 报错说工具不存在但配置里明明写了。这种情况通常是 AI 客户端缓存了旧的配置重启客户端或者重新加载 MCP 配置就能解决。第二个坑浏览器能打开但 AI 找不到页面元素。不一定是 AI 笨很可能是页面里有多套 iframe或者元素需要滚动才能出现。可以先让 AI 把页面 DOM 结构取出来确认元素是否存在再调整 Skill 里的选择器说明。第三个坑Pytest 断言一直失败但手动测试是正常的。这种情况多数是 AI 在操作时忽略了某个前置步骤比如没有等待按钮可用、没有切换窗口。检查 AI 的完整调用链看它在断言前做了什么操作。6. 值得继续投入的方向接口测试、视觉回归、CI 集成如果上面的链路你已经跑通了接下来可以往三个方向扩展把 MCP 对接到接口测试、利用 AI 做视觉回归、把整套流程放到 CI 环境里跑。6.1 接口测试与 MCP 结合WEB 自动化不只是 UI 操作。很多问题在接口层就能发现不需要跑到 UI 这层。你可以把 MCP 连接到 HTTP 请求工具让 AI 直接调用接口并分析返回数据。比如给 AI 一个“查询订单状态”的 Skill让它请求一个接口然后返回状态码和关键字段。Pytest 负责判断状态码是否在预期范围内判断字段值是否符合业务规则。这种方式比 UI 测试快得多适合做冒烟测试和回归测试。6.2 视觉回归让 AI 判断页面样式是否正常传统视觉回归依赖像素比对对细微差异非常敏感容易误报。AI 可以结合截图和自然语言描述判断界面是否符合预期。一个比较可行的实践是让 MCP 工具截图后把图片交给视觉模型分析然后问它页面中是否有按钮重叠、文字溢出、图片加载失败等问题。AI 返回的结论再交给 Pytest 做断言。这里要注意视觉模型的判断有主观性不适合做精确的像素级断言。更适合做“是否有明显布局异常”这种粗粒度检测。如果要做像素级一致还是建议用专门的截图比对工具。6.3 CI 集成AI 测试的稳定性是关键把这套流程放到 CI 上跑最大的问题是环境一致性。AI 客户端的版本、MCP server 的依赖、浏览器驱动版本、模型版本任何一个变化都可能导致测试结果漂移。建议在 CI 环境里固定依赖版本至少锁定主版本号。另外CI 环境里的浏览器必须使用 headless 模式而且很多 CI 容器缺少浏览器运行所需的系统库。可以在容器里预装playwright install --with-deps来解决。日志和报告也要重点设计。AI 测试失败时最好能保留以下三样东西AI 的完整对话记录、MCP 工具调用的请求和响应、以及失败时的页面截图。有了这三样定位问题会快很多。最后说一点建议这套方案真正的价值不在于是不是“AI 自动写测试”而在于让你把重复性的 WEB 操作交给 AI 执行把测试判定逻辑留在自己手里。单条用例跑通不难难的是批量执行时的稳定性。建议先把单条用例的日志、断言和 Skill 定义打磨清楚再扩展到批量场景。如果你还没有配置过任何 MCP建议先用一个最简单的浏览器工具连接通再往里面加业务逻辑。环境越简单问题越容易定位。