图片

一、前言

前面的教程演示了 AI 自动化测试的自愈机制,让测试脚本在元素变动时能自动修复,提高了稳定性。

企业级实战:从告警到自动修复的工程化落地(Playwright + DeepSeek,Python 实战)

但是,在实际业务场景中,单一的输入往往不足以覆盖各种情况。例如:

  • • 电商结账时,收件人可能有不同的地址格式;

  • • 登录时,可能有不同的用户名和密码组合;

  • • 搜索功能,可能要输入不同关键词。

这就需要 数据驱动测试(DDT):一次性编写测试逻辑,通过多组数据覆盖更多情况。

进一步,AI(这里使用 DeepSeek 模型)可以帮助我们:

  • • 自动生成更多测试数据,模拟真实用户场景;

  • • 补充边界情况(极长字符串、异常字符、缺失字段等);

  • • 动态更新数据集,避免人工维护。


二、实战案例

2.1 环境准备

<span></span><code><span leaf="">pip install playwright pytest faker openai</span><br><span leaf="">playwright install</span></code>

⚠️ 注意:这里的 openai 库同样适用于 DeepSeek,只需要配置 API Key 和 Base URL。

在代码里配置 DeepSeek API:

<span></span><code><span><span leaf="">import</span></span><span leaf="">&nbsp;openai</span><br><br><span leaf="">openai.api_key =</span><span><span leaf="">&nbsp;"YOUR_DEEPSEEK_API_KEY"</span></span><br><span leaf="">openai.base_url =</span><span><span leaf="">&nbsp;"https://api.deepseek.com"</span></span></code>

2.2 AI 生成测试数据

我们使用 DeepSeek 生成电商结账场景的 用户信息(包括边界值):

<span></span><code><span><span leaf="">def</span></span><span><span leaf="">&nbsp;generate_user_data_with_ai</span></span><span leaf="">():</span><br><span leaf="">&nbsp; &nbsp; prompt =</span><span><span leaf="">&nbsp;"""</span><br><span leaf="">请生成 5 组电商结账的用户信息,包含:</span><br><span leaf="">- firstName</span><br><span leaf="">- lastName</span><br><span leaf="">- postalCode</span><br><span leaf="">要包含正常值和异常边界值(如超长、特殊字符、缺失)。</span><br><span leaf="">输出 JSON 格式。</span><br><span leaf="">"""</span></span><br><span leaf="">&nbsp; &nbsp; response = openai.ChatCompletion.create(</span><br><span leaf="">&nbsp; &nbsp; &nbsp; &nbsp; model=</span><span><span leaf="">"deepseek-chat"</span></span><span leaf="">,</span><br><span leaf="">&nbsp; &nbsp; &nbsp; &nbsp; messages=[{</span><span><span leaf="">"role"</span></span><span leaf="">:</span><span><span leaf="">"user"</span></span><span leaf="">,</span><span><span leaf="">"content"</span></span><span leaf="">:prompt}]</span><br><span leaf="">&nbsp; &nbsp; )</span><span><br><span leaf="">&nbsp; &nbsp; return</span></span><span leaf="">&nbsp;response.choices[</span><span><span leaf="">0</span></span><span leaf="">].message[</span><span><span leaf="">"content"</span></span><span leaf="">]</span></code>

2.3 Playwright 测试用例

<span></span><code><span><span leaf="">import</span></span><span leaf="">&nbsp;json</span><span><br><span leaf="">import</span></span><span leaf="">&nbsp;pytest</span><span><br><span leaf="">from</span></span><span leaf="">&nbsp;playwright.sync_api</span><span><span leaf="">&nbsp;import</span></span><span leaf="">&nbsp;sync_playwright</span><span><br><span leaf="">from</span></span><span leaf="">&nbsp;utils.ai_data</span><span><span leaf="">&nbsp;import</span></span><span leaf="">&nbsp;generate_user_data_with_ai</span><span><br><br><span leaf="">@pytest.mark.parametrize(</span><span><span><span leaf="">"user"</span></span><span leaf="">, json.loads(</span><span><span leaf="">generate_user_data_with_ai(</span><span></span><span leaf="">)</span></span><span leaf="">)</span></span><span leaf="">)</span></span><span><br><span leaf="">def</span></span><span><span leaf="">&nbsp;test_checkout_with_ddt</span></span><span leaf="">(</span><span><span leaf="">user</span></span><span leaf="">):</span><span><br><span leaf="">&nbsp; &nbsp; with</span></span><span leaf="">&nbsp;sync_playwright()</span><span><span leaf="">&nbsp;as</span></span><span leaf="">&nbsp;p:</span><br><span leaf="">&nbsp; &nbsp; &nbsp; &nbsp; browser = p.chromium.launch(headless=</span><span><span leaf="">True</span></span><span leaf="">)</span><br><span leaf="">&nbsp; &nbsp; &nbsp; &nbsp; page = browser.new_page()</span><br><span leaf="">&nbsp; &nbsp; &nbsp; &nbsp; page.goto(</span><span><span leaf="">"https://www.saucedemo.com"</span></span><span leaf="">)</span><span><br><br><span leaf="">&nbsp; &nbsp; &nbsp; &nbsp; # 登录</span></span><br><span leaf="">&nbsp; &nbsp; &nbsp; &nbsp; page.fill(</span><span><span leaf="">"#user-name"</span></span><span leaf="">,</span><span><span leaf="">&nbsp;"standard_user"</span></span><span leaf="">)</span><br><span leaf="">&nbsp; &nbsp; &nbsp; &nbsp; page.fill(</span><span><span leaf="">"#password"</span></span><span leaf="">,</span><span><span leaf="">&nbsp;"secret_sauce"</span></span><span leaf="">)</span><br><span leaf="">&nbsp; &nbsp; &nbsp; &nbsp; page.click(</span><span><span leaf="">"#login-button"</span></span><span leaf="">)</span><span><br><br><span leaf="">&nbsp; &nbsp; &nbsp; &nbsp; # 添加商品</span></span><br><span leaf="">&nbsp; &nbsp; &nbsp; &nbsp; page.click(</span><span><span leaf="">".btn_inventory"</span></span><span leaf="">)</span><br><span leaf="">&nbsp; &nbsp; &nbsp; &nbsp; page.click(</span><span><span leaf="">".shopping_cart_link"</span></span><span leaf="">)</span><br><span leaf="">&nbsp; &nbsp; &nbsp; &nbsp; page.click(</span><span><span leaf="">"#checkout"</span></span><span leaf="">)</span><span><br><br><span leaf="">&nbsp; &nbsp; &nbsp; &nbsp; # 使用 AI 生成的用户数据</span></span><br><span leaf="">&nbsp; &nbsp; &nbsp; &nbsp; page.fill(</span><span><span leaf="">"#first-name"</span></span><span leaf="">, user.get(</span><span><span leaf="">"firstName"</span></span><span leaf="">,</span><span><span leaf="">""</span></span><span leaf="">))</span><br><span leaf="">&nbsp; &nbsp; &nbsp; &nbsp; page.fill(</span><span><span leaf="">"#last-name"</span></span><span leaf="">, user.get(</span><span><span leaf="">"lastName"</span></span><span leaf="">,</span><span><span leaf="">""</span></span><span leaf="">))</span><br><span leaf="">&nbsp; &nbsp; &nbsp; &nbsp; page.fill(</span><span><span leaf="">"#postal-code"</span></span><span leaf="">, user.get(</span><span><span leaf="">"postalCode"</span></span><span leaf="">,</span><span><span leaf="">""</span></span><span leaf="">))</span><br><br><span leaf="">&nbsp; &nbsp; &nbsp; &nbsp; page.click(</span><span><span leaf="">"#continue"</span></span><span leaf="">)</span><span><br><br><span leaf="">&nbsp; &nbsp; &nbsp; &nbsp; # 简单断言:进入下一个页面</span></span><span><br><span leaf="">&nbsp; &nbsp; &nbsp; &nbsp; assert</span></span><span><span leaf="">&nbsp;"Checkout: Overview"</span></span><span><span leaf="">&nbsp;in</span></span><span leaf="">&nbsp;page.text_content(</span><span><span leaf="">"body"</span></span><span leaf="">)</span><br><br><span leaf="">&nbsp; &nbsp; &nbsp; &nbsp; browser.close()</span></code>

这里通过 pytest.mark.parametrize 动态注入 AI 生成的数据,测试一次可覆盖多种场景。


三、结语

本篇展示了 AI 辅助数据驱动测试 的实践:

  • • ✅ 使用 DeepSeek 生成多组测试数据,涵盖正常与异常场景;

  • • ✅ 结合 pytest 参数化,快速扩展用例覆盖面;

  • • ✅ 提升了测试灵活性和维护效率。


👉 问题给读者:
如果让 AI 来判定「页面是否加载正常」,你觉得最好的触发点是什么?截图对比?DOM 节点?还是日志分析?