5分钟用AI+Selenium打造智能Web自动化测试工具,降低脚本编写门槛

1. 项目概述:当AI遇上自动化测试

最近在团队里搞自动化测试,发现一个挺普遍的问题:写Selenium脚本,尤其是那些复杂的业务流和元素定位,对很多刚入门的测试同学或者开发同学来说,门槛不低。你得懂点Python,熟悉HTML结构,还得会处理各种等待、弹窗和动态加载。往往一个简单的登录测试,从环境搭建到脚本稳定运行,半天就过去了。

就在琢磨怎么把这件事变得更“傻瓜式”一点的时候,我注意到了快马AI。这玩意儿本质上是一个AI代码生成工具,你可以用自然语言描述你的需求,它就能给你生成可运行的代码片段。我当时就想,能不能把它和Selenium这个老牌自动化框架结合起来,让AI来帮我们写那些繁琐的定位和操作代码,而我们只需要关注测试逻辑本身?这个想法一冒出来,我就动手试了试,结果还真让我在5分钟内拼出了一个能跑起来的、具备基础智能的Web自动化测试工具原型。它不只是一个脚本生成器,更是一个“需求翻译器”——你把想测的网页操作用大白话说出来,它负责转化成可执行的Selenium代码。

这个工具特别适合几类人:一是测试新手,想快速上手自动化又怕写代码;二是业务测试人员,需要快速为频繁变动的页面生成测试用例;三是开发同学,想在自测环节快速验证前端页面的关键流程。它的核心价值在于大幅降低自动化测试的初始编写成本,让你能把精力集中在测试用例设计和业务验证上,而不是和XPathCSS Selector较劲。

2. 核心思路:让AI成为你的“脚本助理”

这个项目的核心思路非常直接:人机协同,分工明确。我们不再需要从头到尾手动编写每一行Selenium代码,而是构建一个工作流,让AI承担代码生成的重任,我们则负责提供指令、组装和运行。

2.1 架构设计:三层协作模型

我设计的这个智能工具,可以看作一个三层结构:

  1. 指令层(用户输入):这是最上层,也是我们交互的地方。你只需要用自然语言描述测试步骤。比如:“打开百度首页,在搜索框输入‘快马AI’,点击搜索按钮,然后检查结果页面是否包含‘快马’这个词。” 越具体、越清晰越好。

  2. 翻译层(快马AI):这是核心的智能中间件。它的任务是将你的自然语言指令,解析并翻译成标准的Selenium Python代码。这个过程包括:

    • 意图识别:理解“打开”、“输入”、“点击”、“检查”这些动作。
    • 元素定位推断:根据“搜索框”、“搜索按钮”等描述,结合对常见网页结构的理解,生成最有可能的元素定位策略(如通过name=‘wd’定位百度搜索框)。
    • 代码结构化:生成包含必要的导入语句(from selenium import webdriver)、WebDriver初始化、操作步骤和断言逻辑的完整代码块。
  3. 执行层(Selenium):这是底层执行引擎。它接收由快马AI生成的、格式规范的Python代码,调用本地或远程的浏览器驱动(如ChromeDriver),忠实地执行每一个操作命令,并返回实际结果。

这个架构的优势在于解耦。快马AI的模型能力升级了,我们的工具就能生成更精准、更健壮的代码,而底层的Selenium执行引擎保持稳定。我们作为使用者,始终面对的是最友好的人类语言。

2.2 为什么是快马AI + Selenium?

市面上AI代码助手不少,为什么选快马AI?而Web自动化框架也有Playwright、Cypress等后起之秀,为什么还是Selenium?

  • 选择快马AI的考量:经过对比测试,我发现快马AI在生成Python脚本,特别是基于流行库(如Selenium、Requests)的脚本方面,准确率和上下文理解能力相当不错。它能较好地理解“等待元素出现”、“切换到新窗口”、“处理下拉列表”这类测试场景中的常见指令。更重要的是,它的输出通常是即用型代码片段,而非长篇大论的解释,这正好符合我们“快速生成”的需求。当然,你也可以用其他优秀的AI助手,核心思路是相通的。

  • 坚持Selenium的原因:Selenium虽然是“老将”,但它的生态极其成熟、稳定,社区支持强大,几乎支持所有主流浏览器和编程语言。这意味着AI生成的代码有最广泛的应用基础。Playwright虽然更现代,在某些方面(如自动等待)有优势,但其API和生态相对较新,AI模型对它的“熟悉程度”可能不如对Selenium那么高,生成代码的准确率可能存在波动。对于追求稳定和普适性的快速工具原型,Selenium目前仍是更稳妥的基石。

注意:AI生成的代码并非百分百完美。它可能选择不够优化的定位方式,或者遗漏一些必要的异常处理(如元素未找到、超时)。因此,我们的角色从“编码者”变成了“代码审查者和组装者”。生成后,我们仍需快速浏览并微调代码,这是保证脚本健壮性的关键一步。

3. 五分钟快速搭建实战

理论说再多不如动手做一遍。下面我就带你一步步,在五分钟内把这个工具搭起来。前提是你已经有一个可用的Python环境(3.6以上)和pip。

3.1 环境准备与依赖安装

首先,我们得把“原材料”备齐。打开你的终端或命令行。

  1. 安装Selenium库:这是我们的执行引擎。

    pip install selenium
  2. 下载浏览器驱动:Selenium需要通过驱动来控制浏览器。以最常用的Chrome为例:

    • 查看你电脑上Chrome浏览器的版本(在浏览器地址栏输入chrome://settings/help)。
    • 访问 ChromeDriver 的官方镜像站(如 https://chromedriver.chromium.org/ 或国内的淘宝镜像),下载与你的Chrome版本号完全一致的驱动。
    • 将下载的chromedriver(Windows是.exe)文件放在一个你知道的目录,例如C:\WebDriver\/usr/local/bin/关键一步:要将这个目录添加到系统的环境变量PATH中,这样Python才能找到它。或者,你也可以在代码中指定驱动的绝对路径。
  3. 准备快马AI的访问方式:你需要有一个快马AI的账户,并获取其API密钥。通常在其官网的用户设置或开发者页面可以找到。我们将用这个API密钥来与快马AI的服务进行通信。

3.2 构建核心AI指令翻译模块

环境好了,我们来写这个工具最核心的部分——一个能与快马AI对话并获取代码的函数。我们将使用requests库来调用其API。

import requests import json def generate_selenium_code_with_kaimaai(instruction, api_key): """ 使用快马AI API,根据自然语言指令生成Selenium代码。 参数: instruction (str): 自然语言描述的测试步骤。 api_key (str): 你的快马AI API密钥。 返回: str: 生成的Python代码字符串,如果失败则返回None。 """ # 快马AI的API端点(示例,请以官方最新文档为准) url = "https://api.kaimaai.com/v1/completions" # 构建请求头,包含认证信息 headers = { "Content-Type": "application/json", "Authorization": f"Bearer {api_key}" } # 精心设计的提示词(Prompt),这是决定生成质量的关键! prompt = f""" 你是一个资深的Python自动化测试工程师。请将以下测试需求转化为可直接运行的Python Selenium代码。 要求: 1. 使用 selenium.webdriver 库。 2. 代码结构清晰,包含必要的导入和WebDriver初始化(假设使用Chrome)。 3. 为每个操作步骤添加简要的注释。 4. 对于查找元素,优先使用稳定可靠的定位方式,如ID、name,其次是CSS Selector。 5. 包含必要的等待(推荐使用WebDriverWait和expected_conditions)。 6. 最后,使用assert语句进行结果验证。 测试需求:{instruction} 请只输出代码,不要有任何额外的解释。 """ # 构建请求数据体 data = { "model": "kaima-code-002", # 假设的代码生成模型,请根据实际情况调整 "prompt": prompt, "max_tokens": 1500, # 生成代码的最大长度 "temperature": 0.2, # 较低的温度值使输出更确定、更专注于代码 } try: response = requests.post(url, headers=headers, data=json.dumps(data)) response.raise_for_status() # 检查HTTP请求是否成功 result = response.json() # 假设API返回的代码在 'choices' 字段的 'text' 中 generated_code = result['choices'][0]['text'].strip() return generated_code except requests.exceptions.RequestException as e: print(f"请求快马AI API失败: {e}") return None except (KeyError, json.JSONDecodeError) as e: print(f"解析API响应失败: {e}") return None

代码解读与心得

  • 提示词(Prompt)工程是关键:AI的表现很大程度上取决于你如何“提问”。上面的Prompt明确限定了角色、技术栈、代码风格和要求。特别强调了“稳定的定位方式”和“必要的等待”,这是生成高质量Selenium代码的命门。你可以根据实际需要调整这个Prompt。
  • 错误处理必不可少:网络请求和API响应解析都可能出错,用try-except包裹起来能让你的工具更健壮。
  • 温度参数temperature设为0.2左右,是为了让AI生成更保守、更可靠的代码,减少天马行空的“创意”。

3.3 组装与执行:打造完整工作流

有了代码生成器,我们还需要一个“主控程序”来串联一切:接收用户输入、调用AI、保存并执行生成的代码。

import os import subprocess import sys import tempfile def main(): print("欢迎使用智能Web自动化测试脚本生成器!") print("请输入你的测试需求(例如:打开百度,搜索Selenium,检查标题)。") print("输入 'quit' 退出程序。") # 替换为你的实际API密钥 KAI_MA_AI_API_KEY = "your_kaimaai_api_key_here" while True: user_instruction = input("\n请输入测试需求: ").strip() if user_instruction.lower() == 'quit': print("再见!") break if not user_instruction: print("输入不能为空,请重新输入。") continue print("\n正在向快马AI请求生成代码...") selenium_code = generate_selenium_code_with_kaimaai(user_instruction, KAI_MA_AI_API_KEY) if not selenium_code: print("代码生成失败,请检查API密钥或网络连接。") continue print("代码生成成功!") print("-" * 50) print(selenium_code) print("-" * 50) # 询问用户是否执行 choice = input("\n是否要立即执行生成的代码?(y/n): ").strip().lower() if choice == 'y': execute_generated_code(selenium_code) else: print("代码已生成,您可以选择保存到文件。") save_choice = input("是否保存到文件?(y/n): ").strip().lower() if save_choice == 'y': filename = input("请输入文件名(例如:test_baidu.py): ").strip() if not filename.endswith('.py'): filename += '.py' with open(filename, 'w', encoding='utf-8') as f: f.write(selenium_code) print(f"代码已保存至 {filename}") def execute_generated_code(code_string): """ 在一个临时的Python文件中执行生成的代码。 这是一种安全且隔离的执行方式。 """ # 创建一个临时文件 with tempfile.NamedTemporaryFile(mode='w', suffix='.py', delete=False, encoding='utf-8') as tmp_file: tmp_file.write(code_string) tmp_file_path = tmp_file.name try: print("开始执行自动化测试...") # 使用当前Python解释器执行临时文件 result = subprocess.run([sys.executable, tmp_file_path], capture_output=True, text=True, timeout=60) # 设置60秒超时 print("\n--- 执行输出 ---") if result.stdout: print("标准输出:", result.stdout) if result.stderr: print("标准错误:", result.stderr) print(f"返回码: {result.returncode}") print("--- 执行结束 ---") except subprocess.TimeoutExpired: print("错误:测试执行超时(60秒),可能陷入无限等待或浏览器未正常关闭。") except Exception as e: print(f"执行过程中发生未知错误: {e}") finally: # 清理临时文件 os.unlink(tmp_file_path) print("临时文件已清理。") if __name__ == "__main__": main()

设计思路与避坑指南

  • 临时文件执行:为什么不直接用exec(code_string)?因为exec在执行复杂代码,尤其是涉及导入、全局变量时,作用域管理很麻烦,容易污染当前环境。写入临时文件再用subprocess调用,相当于启动了一个全新的、干净的Python进程来运行这段代码,隔离性好,也更安全。
  • 超时控制:自动化测试可能因为元素找不到而无限等待。设置timeout参数可以防止程序卡死,这是一个非常重要的防护措施。
  • 输出捕获:通过capture_output=True捕获子进程的输出和错误,方便我们查看测试执行过程中的打印信息或异常。

4. 实战演练:从需求到自动化测试报告

光说不练假把式。我们用一个真实的例子走一遍全流程,看看效果如何。

4.1 案例:自动化测试百度搜索功能

第一步:启动工具并输入需求运行我们刚刚写好的main()函数。程序启动后,输入我们的测试需求:

“打开百度首页(https://www.baidu.com),等待页面加载完成。在搜索输入框里输入‘人工智能’,然后点击‘百度一下’按钮。等待搜索结果页面加载,检查页面标题中是否包含‘人工智能’这个词。最后,关闭浏览器。”

第二步:AI生成代码工具将上述需求发送给快马AI。几秒钟后,我们可能会得到类似下面的代码(注:以下为模拟AI可能生成的代码,非真实API返回):

from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.common.exceptions import TimeoutException # 初始化Chrome浏览器驱动 driver = webdriver.Chrome() try: # 步骤1: 打开百度首页 driver.get("https://www.baidu.com") print("已打开百度首页") # 显式等待页面标题包含“百度” wait = WebDriverWait(driver, 10) wait.until(EC.title_contains("百度")) # 步骤2: 定位搜索框并输入关键词 # 使用ID定位,这是最稳定的方式之一 search_box = driver.find_element(By.ID, "kw") search_box.clear() search_box.send_keys("人工智能") print("已在搜索框输入‘人工智能’") # 步骤3: 定位并点击搜索按钮 search_button = driver.find_element(By.ID, "su") search_button.click() print("已点击‘百度一下’按钮") # 步骤4: 等待搜索结果页面加载,验证标题 # 等待新页面标题出现 wait.until(EC.title_contains("人工智能")) actual_title = driver.title print(f"当前页面标题是: {actual_title}") # 步骤5: 断言验证 assert "人工智能" in actual_title, f"页面标题验证失败!期望包含‘人工智能’,实际为‘{actual_title}’" print("测试通过!页面标题包含‘人工智能’。") except TimeoutException as e: print(f"操作超时: {e}") except Exception as e: print(f"测试执行过程中发生错误: {e}") finally: # 步骤6: 关闭浏览器 driver.quit() print("浏览器已关闭。")

第三步:执行与验证工具询问是否执行,输入y。你会看到Chrome浏览器自动打开,访问百度,输入文字,点击搜索,然后浏览器关闭。控制台会打印出每一步的日志。如果一切顺利,最后会看到“测试通过!”的字样。

第四步:代码优化与保存AI生成的代码已经非常可用,但作为有经验的工程师,我们可能会做一点微调:

  1. 增加隐式等待:在初始化driver后,可以加一行driver.implicitly_wait(10),作为全局的等待策略,辅助显式等待。
  2. 更精确的等待条件:等待搜索结果页面时,EC.title_contains可能不够精确。有时可以改为等待某个特定结果元素出现,如wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, “.result.c-container”)))
  3. 添加截图功能:在断言失败时,自动截屏保存证据,便于后续分析。可以在except AssertionError as e:块中添加driver.save_screenshot(“error_screenshot.png”)

调整完毕后,可以选择将最终版的代码保存到本地文件,比如test_baidu_search.py,以后就可以直接运行这个脚本了。

4.2 处理更复杂的场景

AI的能力不止于此。你可以尝试更复杂的需求,比如:

  • 需求:“测试登录功能:打开某电商网站登录页,输入用户名‘test@example.com’和密码‘123456’,勾选‘记住我’,点击登录。登录成功后,检查页面右上角是否显示‘我的账户’链接。”
  • AI的挑战与应对:这个需求涉及表单填写、复选框操作和登录后状态验证。AI需要生成处理输入框、复选框点击以及验证特定链接存在的代码。生成的代码可能会使用By.NAMEBy.XPATH来定位用户名和密码框。关键点:对于“记住我”这类复选框,AI需要生成element.click()来切换状态;对于登录后的验证,可能需要等待页面跳转完成后再查找元素。

实操心得:面对复杂场景,你的指令要尽可能分解。与其给一个长句,不如分步骤描述,甚至可以先让AI生成登录步骤的代码,验证通过后,再让它生成登录后操作的代码。这种“分而治之”的策略,能显著提高AI生成代码的准确率和可用性。

5. 进阶技巧与效能提升

工具跑起来只是第一步,要想让它真正成为生产力,还需要一些“打磨”。

5.1 编写高质量的AI指令(Prompt)

你的指令质量直接决定输出代码的质量。以下是几个原则:

  • 具体明确:避免“操作那个按钮”这种模糊说法,用“点击ID为‘submitBtn’的按钮”或“点击‘登录’按钮”。
  • 提供上下文:对于非大众化网站,可以提供关键元素的ID或Class。例如:“在网站(URL)上,有一个class为‘search-input’的搜索框...”。
  • 设定约束:在Prompt中明确技术栈、编码风格(如PEP 8)、是否需要异常处理、是否使用Page Object模式等。
  • 迭代优化:如果第一次生成的代码不理想,不要放弃。根据问题调整你的指令,比如:“上次生成的代码定位元素用了XPath,但那个元素有ID,请改用ID定位。” AI可以从对话历史中学习。

5.2 集成测试框架(如Pytest)

目前我们的工具生成的是独立脚本。要融入CI/CD流程,最好能集成进测试框架。我们可以修改AI的Prompt,让它直接生成Pytest格式的测试用例。

优化后的Prompt示例: “...请将以下测试需求转化为一个Pytest测试函数。函数名以test_开头。使用@pytest.fixture来管理driver的生命周期。测试步骤中请使用清晰的断言...”

这样生成的代码可以直接放入test_*.py文件中,用pytest命令批量执行并生成漂亮的测试报告。

5.3 构建可复用的代码库与模板

随着使用次数增多,你会发现AI生成的代码有共通之处。我们可以构建一个基础模板或函数库:

  1. 创建基础操作函数:将“打开浏览器”、“查找元素(带重试)”、“输入文本”、“点击”、“截图”等操作封装成函数。
  2. 修改AI Prompt:让AI在生成代码时,调用这些封装好的函数,而不是每次都生成原始的driver.find_elementelement.click。例如:“...请使用我们项目中的safe_click(driver, locator)函数来点击元素,该函数已内置显式等待...”
  3. 配置管理:将浏览器类型、默认等待时间、基础URL等提取到配置文件(如config.yaml)中,让AI生成的代码能读取这些配置。

这样做,AI生成的代码将更符合项目规范,也更健壮。

6. 常见问题与排查手册

在实际使用中,你肯定会遇到各种问题。这里我整理了一份“踩坑”实录。

6.1 AI生成代码的典型问题与修复

问题现象可能原因排查与修复方法
代码执行时报NoSuchElementExceptionAI生成的元素定位器不准或过时;页面尚未加载完成。1.手动验证:在浏览器开发者工具中,用AI生成的定位器(如XPath)尝试查找,看是否能唯一匹配目标元素。
2.增加等待:在操作元素前,添加显式等待WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, “element_id”)))
3.优化定位器:优先使用ID、name等稳定属性。避免使用绝对XPath或依赖动态class的CSS选择器。
浏览器闪退或无法启动ChromeDriver版本与Chrome浏览器版本不匹配;驱动路径未正确设置。1.检查版本:确认ChromeDriver版本与Chrome浏览器主版本号一致。
2.检查PATH:确认ChromeDriver所在目录已添加到系统PATH,或在代码中指定绝对路径webdriver.Chrome(executable_path=‘/path/to/chromedriver’)
3.查看日志:初始化driver时添加service_log_path=‘chromedriver.log’参数,查看详细的驱动日志。
执行速度很慢AI生成的代码可能使用了过多的time.sleep()或缺乏高效的等待策略。1.替换sleep:将time.sleep(5)替换为显式等待WebDriverWait(driver, 10).until(EC.condition)
2.启用隐式等待:在driver初始化后设置driver.implicitly_wait(10),作为查找元素的全局超时。
3.检查网络:确保测试环境网络通畅。
断言失败,但页面看起来正常AI生成的断言条件可能过于严格或不准确(例如,检查的文本有空格或大小写问题)。1.打印调试:在断言前,打印出实际获取到的文本或属性值,与预期值仔细对比。
2.模糊匹配:使用assert “关键词” in actual_text而非assert actual_text == “完整句子”
3.清理数据:使用.strip()去除字符串首尾空格。
无法处理弹窗/新窗口AI可能没有生成切换窗口或处理alert的代码。1.切换窗口:在点击可能打开新窗口的链接后,添加driver.switch_to.window(driver.window_handles[-1])切换到最新窗口。
2.处理Alert:使用Alert(driver).accept()Alert(driver).dismiss()。需要在Prompt中明确告知AI此类场景。

6.2 提升脚本稳定性的关键点

  1. 定位器策略:这是Selenium脚本稳定的基石。绝对不要依赖AI生成复杂的、包含索引的XPath(如/html/body/div[3]/div[2]/div[5]/a[1]。这类定位器极其脆弱,页面结构稍有变动就会失效。指导AI使用ID、唯一的name属性,或者简洁的CSS选择器(如input.search-input)。
  2. 等待的艺术:区分“存在”、“可见”、“可点击”。presence_of_element_located只要求元素在DOM中存在(可能隐藏),visibility_of_element_located要求元素可见,element_to_be_clickable要求元素可交互。根据你的操作意图选择正确的等待条件。
  3. 失败重试机制:对于不稳定的操作(如网络波动导致的元素加载慢),可以在代码外层包裹一个简单的重试循环。或者使用更高级的库如retrying
  4. 环境隔离:每次测试都使用全新的浏览器实例(无缓存、无Cookies的匿名模式),可以避免因旧数据导致的意外行为。可以在初始化driver时添加选项:options.add_argument(“--incognito”)

6.3 关于Playwright与Selenium选择的再思考

在项目热词里也看到了Playwright。这里简单说一下我的看法:如果你的项目是全新的,且团队对Node.js/Python/.NET/C#接受度良好,Playwright确实是一个强大的选择,它内置了自动等待、强大的录制工具和跨浏览器支持。但是,对于我们“5分钟快速打造智能工具”这个目标而言,Selenium的确定性更高。AI模型对Selenium的认知数据更海量,生成代码的“常识”更丰富。Playwright较新,AI可能在某些API的使用上产生混淆。因此,在追求“快速”和“稳定生成”的第一阶段,Selenium是更优解。当你的工具成熟后,完全可以探索让AI生成Playwright脚本,思路是完全一致的。

这个用快马AI加Selenium攒出来的小工具,本质上是一个“生产力杠杆”。它不能替代你对Web自动化测试原理的理解,也不能替代你设计测试用例的思考。但它能把你从重复、繁琐的代码编写中解放出来,让你用描述需求的时间,换来一个可运行、可调试的脚本原型。剩下的优化和集成工作,依然需要你的专业判断。我开始用它来快速生成冒烟测试和核心流程测试的初版脚本,效率提升非常明显。最重要的是,它让团队里那些对代码望而却步的同事,也开始愿意尝试和描述自动化测试用例了,这或许才是它最大的价值。