AI驱动测试实战:Amazon Nova Act与pytest集成,实现自然语言自动化测试
1. 项目概述:当AI成为测试工程师的“副驾驶”
如果你是一名测试工程师,或者正在为团队寻找自动化测试的破局之道,那么最近在圈内被频繁讨论的“AI驱动测试”一定不会陌生。这个概念听起来很酷,但落地起来往往伴随着一堆问号:它到底能做什么?是噱头还是生产力革命?代码怎么写?和现有的pytest框架怎么结合?会不会让我的测试脚本变得更复杂?
今天,我就以一个实战项目的视角,为你拆解“Amazon Nova Act浏览器自动化测试”这个组合方案。这不仅仅是一个工具介绍,更是一次关于如何将AI能力无缝融入现有测试工程体系,并解决真实业务场景(比如我们后面会详细讲的“OpenClaw”场景)的深度实践。简单来说,它的核心是:用自然语言告诉AI你想测什么,AI帮你生成并执行浏览器操作,同时你还能用熟悉的pytest来组织、断言和生成报告,实现“所想即所测”。
想象一下,以前你要写一个“在亚马逊上搜索无线耳机,找到评分最高的商品,检查价格,如果低于500美元就加入购物车”的测试用例。你需要用Selenium或Playwright定位搜索框、结果列表、价格元素、按钮,处理页面加载和元素状态,写一堆find_element和click()。现在,你只需要用一行接近人类语言的指令:nova.act(“search for a wireless earbuds, select the Top Rated item, check the price, if price is less than $500, add to list”)。剩下的页面导航、元素查找、逻辑判断,AI会自己“思考”并完成。
这背后依赖的是Amazon Nova Act这个专门为浏览器操作训练的AI模型,以及AgentCore Browser Tool提供的云端、安全的浏览器执行环境。而pytest,则扮演着测试脚手架和质量管理员的角色,负责用例的组织、数据驱动、断言校验和精美的Allure报告生成。本次实战,我将带你从零搭建环境,编写第一个AI测试用例,集成pytest,并最终在一个名为“OpenClaw”的复杂业务场景中落地,展示其处理动态内容、多步骤流程和异常恢复的真实能力。你会发现,AI不是来取代测试工程师的,而是成为一个不知疲倦、理解力超强的“副驾驶”,让我们从繁琐的脚本维护中解放出来,更专注于测试设计、业务验证和深度缺陷挖掘。
2. 核心组件深度解析:Nova Act、AgentCore与pytest如何协同
在开始敲代码之前,我们必须先理解这套技术栈里每个核心部件扮演的角色,以及它们是如何像齿轮一样精密咬合在一起的。很多人在初次接触时会混淆Nova Act和AgentCore,或者不明白pytest在这里的价值,导致上手困难。
2.1 Amazon Nova Act:会“思考”的浏览器操作大脑
Nova Act不是一个普通的自动化库。你可以把它理解为一个专门针对浏览器环境进行了强化训练的AI智能体(Agent)。它的输入是自然语言指令,输出则是一系列在浏览器中执行的具体动作(点击、输入、滚动等)。关键在于它的“思考”过程:
- 感知(Perception):接收当前浏览器页面的截图和DOM结构,理解屏幕上有什么。
- 规划(Planning):基于你的指令(如“搜索无线耳机”)和当前页面状态,规划出达成目标所需的步骤序列。例如:“首先,我需要找到搜索框;然后,在里面输入‘wireless earbuds’;最后,点击搜索按钮或按回车。”
- 执行(Execution):将规划好的步骤转化为浏览器自动化工具(底层通常是Playwright)能够执行的命令。
- 观察(Observation):执行后,再次感知页面变化,判断是否成功,或者是否需要调整策略。
这个过程在一个循环中持续进行,直到任务完成或达到最大尝试次数。这模仿了人类操作浏览器的过程:看一眼,想一下,做一步,再看结果。因此,Nova Act对现代动态Web应用(大量JavaScript,元素频繁变化)的适应性远超传统基于固定定位符(如XPath、CSS Selector)的脚本。当页面布局微调时,AI可能依然能通过视觉和语义理解找到“那个看起来像搜索框的地方”,而传统脚本则会因定位器失效而报错。
2.2 AgentCore Browser Tool:安全、可扩展的云端“双手”
Nova Act负责思考,但它需要一个安全、可靠的环境来执行动作。这就是AgentCore Browser Tool的用武之地。你可以把它看作AWS托管的一个无头浏览器集群服务。它解决了本地运行浏览器自动化的几个核心痛点:
- 环境一致性:测试在云端统一的浏览器环境中运行,避免了“在我机器上好好的”这类问题。你可以指定浏览器类型和版本。
- 资源与可扩展性:无需在本地维护复杂的浏览器和驱动环境。需要执行大量并发测试时,可以轻松横向扩展。
- 企业级安全:浏览器运行在隔离的容器中,执行完毕后状态清零,防止数据泄露。所有操作通过安全的WebSocket连接进行。
- 可视化与调试:它提供了会话录制和实时查看器(Browser Viewer),你可以像看监控一样观察AI每一步操作,这对于调试复杂的AI决策过程至关重要。
Nova Act通过Chrome DevTools Protocol (CDP) 连接到AgentCore Browser Tool提供的浏览器实例。这意味着,你既可以用Nova Act驱动,也可以在同一CDP会话上,用传统的Playwright或Puppeteer库进行更精细的手动控制,实现“AI自动化”与“脚本自动化”的混合编排,灵活性极高。
2.3 pytest:不可或缺的测试框架基石
有人可能会问:既然AI都能自己执行了,还要pytest干嘛?pytest在这里的作用是工程化与专业化,它将AI的“单次任务执行”提升为可维护、可重复、可报告的“测试用例”。
- 用例组织与夹具(Fixtures):pytest的fixture是管理测试资源的利器。我们可以创建一个
nova_act_fixture,负责初始化Nova Act会话、连接到AgentCore浏览器、并在测试结束后清理资源。所有测试用例只需调用这个fixture即可获得一个配置好的Nova Act实例。 - 参数化与数据驱动:我们可以用
@pytest.mark.parametrize轻松实现数据驱动测试。例如,用不同的搜索关键词和价格阈值来测试购物流程。 - 强大的断言:Nova Act执行后会返回结果。我们可以用pytest的
assert语句,结合Python丰富的表达式,对返回的文本、结构化的JSON数据进行精确验证。 - 插件生态与报告:这是pytest的王牌。集成
pytest-html可以生成HTML报告,集成allure-pytest可以生成极其美观且信息丰富的Allure报告,展示测试步骤、截图(来自AgentCore的实时视图)、日志和AI的“思考”过程,让测试结果一目了然。 - 并发执行与调度:pytest可以与
pytest-xdist插件结合,实现测试用例的并行运行,充分利用AgentCore云端浏览器的弹性,大幅缩短测试套件的执行时间。
三者关系总结:pytest是导演和制片人,负责整个测试项目的编排、质量和成片(报告);Nova Act是拥有自主决策能力的主演,负责理解剧本(自然语言指令)并完成表演(浏览器操作);AgentCore Browser Tool是摄影棚和后勤保障,提供稳定、安全的拍摄场地和设备支持。三者结合,才能拍出一部高质量的“测试大片”。
3. 环境搭建与第一个AI驱动测试用例
理论讲得再多,不如动手跑一遍。我们来一步步搭建环境,并写出第一个能真正运行的测试。这里我会补充很多官方文档可能一笔带过,但实际操作中必然会遇到的细节。
3.1 前期准备与依赖安装
首先,你需要一个AWS账户,并确保在支持Bedrock服务的区域(例如us-west-2)启用了相关服务。接着,在Amazon Nova Act官网获取你的API密钥,这是调用Nova Act模型的凭证。
然后,我们创建一个干净的Python虚拟环境并安装核心依赖。我强烈建议使用pyproject.toml或requirements.txt来管理依赖,确保团队环境一致。
# 创建并激活虚拟环境 python -m venv .venv source .venv/bin/activate # Linux/macOS # .venv\Scripts\activate # Windows # 安装核心库 pip install bedrock-agentcore # AgentCore Browser Tool客户端 pip install playwright # 底层浏览器自动化驱动,Nova Act依赖它 pip install nova-act # Nova Act AI模型客户端 pip install pytest # 测试框架 pip install pytest-html # 可选,用于生成HTML报告 pip install allure-pytest # 可选,用于生成Allure报告 # 安装Playwright的浏览器内核 playwright install chromium注意:
bedrock-agentcore和nova-act的版本兼容性很重要。实践中遇到过因版本不匹配导致CDP连接失败的问题。建议在项目初期就锁定版本号,例如pip install nova-act==0.1.x。
3.2 编写基础Fixture与第一个测试用例
让我们在test_demo.py中编写第一个测试。首先,创建一个管理Nova Act会话的pytest fixture。
# conftest.py import pytest from nova_act import NovaAct from bedrock_agentcore.tools.browser_client import browser_session @pytest.fixture(scope="function") # 每个测试函数一个独立会话 def nova_act_instance(): """ 创建一个连接到AgentCore Browser Tool的Nova Act实例。 使用`scope="function"`确保测试间隔离。 """ # 启动一个远程浏览器会话,指定区域 with browser_session('us-west-2') as client: # 获取连接浏览器实例所需的WebSocket URL和头部信息 ws_url, headers = client.generate_ws_headers() # 使用CDP端点初始化Nova Act,并传入API密钥 with NovaAct( cdp_endpoint_url=ws_url, cdp_headers=headers, nova_act_api_key="YOUR_NOVA_ACT_API_KEY_HERE", # 替换为你的真实密钥 starting_page="about:blank" # 起始页,后续可导航 ) as nova: yield nova # 将实例提供给测试用例使用 # with块退出时,会自动关闭浏览器会话和Nova Act连接这个fixture做了几件关键事:1) 通过browser_session向AWS申请一个浏览器实例;2) 获取该实例的CDP连接信息;3) 用这些信息初始化Nova Act。yield nova使得测试函数能接收到这个已就绪的对象。
现在,编写第一个真正的测试用例:
# test_first_ai_case.py def test_search_amazon_with_nova_act(nova_act_instance): """ 测试用例:使用Nova Act在亚马逊上搜索商品并提取信息。 验证AI能否理解指令并完成多步操作。 """ nova = nova_act_instance # 第一步:导航到亚马逊 nova.act("go to amazon.com") # 此时AI会打开浏览器,导航到https://www.amazon.com # 第二步:执行搜索 nova.act("search for python programming books") # AI会找到搜索框,输入文本,并触发搜索 # 第三步:获取第一页结果中的第一个商品标题 result = nova.act( "get the title of the first product in the search result list", schema={"type": "object", "properties": {"title": {"type": "string"}}} # 可选:指定期望的JSON结构 ) # 使用pytest进行断言 assert result.response is not None, "AI未返回任何响应" # 你可以进一步解析result.response,它可能是AI返回的自然语言文本 # 如果使用了schema,可以通过result.parsed_response获取结构化数据 print(f"AI返回的结果: {result.response}") # 一个更健壮的断言:检查响应中是否包含一些预期关键词 response_text = result.response.lower() assert any(keyword in response_text for keyword in ["python", "programming", "book"]), \ f"响应中未找到预期关键词。响应内容: {result.response}"运行这个测试:pytest test_first_ai_case.py -v。如果一切配置正确,你会看到浏览器在云端启动,AI执行搜索,并打印出结果。第一次运行可能会慢一些,因为涉及模型调用和浏览器启动。
3.3 核心技巧:如何编写有效的自然语言指令
让AI高效工作的关键,在于给它的指令(Prompt)。经过大量实践,我总结了几个原则:
- 原子化与顺序性:将复杂任务拆解成顺序的、原子化的
act指令。就像上面的例子,先“去网站”,再“搜索”,最后“获取信息”。不要试图在一个act里塞进太多步骤,这容易导致AI困惑或执行路径错误。 - 明确目标与上下文:指令要清晰。
“get the price”就不如“on the current product detail page, find and tell me the current price displayed”明确。后者提供了上下文(当前商品详情页)和精确目标(显示的价格)。 - 利用结构化输出(Schema):当需要提取特定数据时,强烈建议使用
schema参数。这告诉AI你希望它返回一个特定格式的JSON。这比从一大段自然语言文本中用正则表达式解析要可靠得多。例如,提取商品信息:from pydantic import BaseModel class ProductInfo(BaseModel): title: str price: str rating: float = None # 可选字段 result = nova.act( “get the title, price, and star rating of the product shown”, schema=ProductInfo.model_json_schema() ) if result.matches_schema: product = ProductInfo.model_validate(result.parsed_response) print(f”商品: {product.title}, 价格: {product.price}”) - 处理不确定性:AI可能会失败。你的测试代码需要容错。可以结合
try-except,或者利用Nova Act返回的ActResult对象中的元数据(如执行步骤数、耗时)来判断任务执行的健康度。
4. 工程化集成:构建基于pytest的AI测试框架
单个测试用例跑通只是第一步。要用于实际项目,我们必须将其工程化,构建一个健壮、可维护的测试框架。这部分是体现测试架构师价值的地方。
4.1 设计可复用的Fixture与配置管理
上面的基础fixture可以进一步强化。我们通常会将配置(如API密钥、浏览器区域、超时设置)外置到配置文件或环境变量中。
# conftest.py import os import pytest from nova_act import NovaAct from bedrock_agentcore.tools.browser_client import browser_session def pytest_addoption(parser): """添加自定义命令行选项""" parser.addoption("--browser-region", default="us-west-2", help="AgentCore浏览器区域") parser.addoption("--headful", action="store_true", help="是否以有头模式运行(通过Viewer查看)") @pytest.fixture(scope="session") def nova_act_config(request): """会话级配置fixture""" config = { "api_key": os.getenv("NOVA_ACT_API_KEY"), # 从环境变量读取,更安全 "region": request.config.getoption("--browser-region"), "headful": request.config.getoption("--headful"), "default_timeout": 30, # 默认指令超时时间 } if not config["api_key"]: pytest.fail("请设置环境变量 NOVA_ACT_API_KEY") return config @pytest.fixture(scope="function") def nova_act(nova_act_config, request): """主要的Nova Act实例fixture,增加日志和截图能力""" region = nova_act_config['region'] with browser_session(region) as client: ws_url, headers = client.generate_ws_headers() # 如果需要可视化调试,启动Browser Viewer viewer_process = None if nova_act_config['headful']: from browser_viewer import BrowserViewerServer viewer = BrowserViewerServer(client, port=8080) viewer_url = viewer.start(open_browser=False) # 不自动打开,记录URL print(f"? 浏览器查看器地址: {viewer_url}") # 这里需要根据实际情况管理viewer进程,示例中简化处理 with NovaAct( cdp_endpoint_url=ws_url, cdp_headers=headers, nova_act_api_key=nova_act_config['api_key'], starting_page="about:blank", timeout=nova_act_config['default_timeout'] ) as nova_instance: # 为当前测试用例创建一个日志目录 test_name = request.node.name log_dir = f"./logs/{test_name}" os.makedirs(log_dir, exist_ok=True) # 可以在这里配置Nova Act的日志输出路径(如果库支持) yield nova_instance # 测试结束后,可以自动保存最后一次操作的截图或日志 # 例如,通过Playwright CDP连接截图(需要额外代码) print(f”测试 [{test_name}] 执行完毕,日志保存在 {log_dir}”) # 清理viewer if viewer_process: viewer_process.terminate()这个增强版的fixture提供了配置化、可视化调试支持以及测试日志管理的基础结构。
4.2 实现Page Object模式与AI指令的封装
即使使用AI,良好的设计模式依然重要。我们可以将针对特定页面的AI操作封装成“智能Page Object”。
# pages/amazon_home_page.py class AmazonHomePage: def __init__(self, nova_act_instance): self.nova = nova_act_instance def open(self): self.nova.act("go to amazon.com") return self def search_product(self, product_name): """搜索商品,并确保进入结果页""" result = self.nova.act(f"search for {product_name}") # 可以在这里添加一些验证,比如确认页面标题或URL变化 # 如果AI执行失败或未达到预期,可以抛出异常或重试 return result def get_top_rated_product_info(self): """获取当前结果页中评分最高的商品信息(结构化)""" from pydantic import BaseModel class Product(BaseModel): title: str price: str rating: str = None result = self.nova.act( “find the product marked as ‘Top Rated’ or with the highest rating, and give me its title and price”, schema=Product.model_json_schema() ) if result.matches_schema: return Product.model_validate(result.parsed_response) else: # 降级处理:尝试从自然语言响应中提取 # 或者抛出特定异常,供测试用例处理 raise ValueError(“未能解析到结构化的商品信息”) def add_to_cart_if_price_below(self, product_title, threshold): """如果指定商品价格低于阈值,则加入购物车""" # 先导航到该商品详情页(假设通过点击商品标题) self.nova.act(f“click on the product titled ‘{product_title}’“) # 检查价格 price_result = self.nova.act(“read the current price of this product”) # 这里需要一个简单的价格解析逻辑(这是一个简化示例,实际更复杂) import re price_match = re.search(r’\$(\d+\.?\d*)’, price_result.response) if price_match: price = float(price_match.group(1)) if price < threshold: self.nova.act(“click the ‘Add to Cart’ button”) return True, price return False, None在测试用例中,使用起来就非常清晰:
def test_amazon_shopping_flow(nova_act): amazon = AmazonHomePage(nova_act) amazon.open() amazon.search_product(“wireless keyboard”) product = amazon.get_top_rated_product_info() assert product.price is not None added, actual_price = amazon.add_to_cart_if_price_below(product.title, 100.0) if added: print(f“商品 {product.title} 已加入购物车,价格 {actual_price} 低于$100”) else: print(f“商品价格 {actual_price} 高于阈值,未加入购物车”)这种封装将AI指令的业务语义隐藏起来,测试用例更关注业务流,提高了可读性和可维护性。当页面逻辑变更时,只需在一个地方修改AI指令。
4.3 生成详尽的测试报告:集成Allure
pytest的插件生态是我们的强大后盾。集成Allure可以生成包含丰富上下文的测试报告,对于调试AI测试尤其有用。
首先,安装并配置Allure命令行工具。然后在pytest运行时添加参数:
pytest test_amazon_flow.py --alluredir=./allure-results测试结束后,生成报告:
allure serve ./allure-results为了让Allure报告包含AI操作的每一步“思考”和截图,我们需要在fixture或测试用例中钩住这些信息。由于Nova Act库本身可能不直接暴露每一步的详细日志给pytest,我们需要一些技巧。一种方法是在封装指令时,手动将关键信息记录到Allure中:
import allure from allure_commons.types import AttachmentType def act_with_allure_logging(nova_instance, instruction, step_name): """ 包装nova.act,将指令、AI的思考(如果可获取)和结果截图记录到Allure """ with allure.step(f”AI指令: {step_name}“): allure.attach(instruction, name=”自然语言指令“, attachment_type=AttachmentType.TEXT) # 执行指令 result = nova_instance.act(instruction) # 假设我们有一个方法能获取最后一次操作的截图(需要额外实现,例如通过CDP) # screenshot = take_screenshot_via_cdp(nova_instance.cdp_client) # if screenshot: # allure.attach(screenshot, name=”执行后页面“, attachment_type=AttachmentType.PNG) # 将AI的响应也附上 if result.response: allure.attach(result.response, name=”AI响应“, attachment_type=AttachmentType.TEXT) # 记录元数据 metadata_str = f”步骤数: {result.metadata.num_steps_executed}, 耗时: {result.metadata.end_time - result.metadata.start_time}“ allure.attach(metadata_str, name=”执行元数据“, attachment_type=AttachmentType.TEXT) return result # 在测试用例中使用 def test_with_allure(nova_act): result = act_with_allure_logging(nova_act, “go to github.com”, “导航到GitHub”) # ... 更多步骤这样生成的Allure报告,每个测试步骤都清晰记录了AI收到了什么指令、返回了什么、页面当时是什么样子,极大地便利了失败用例的复盘和调试。
5. 复杂场景实战:OpenClaw工作流自动化测试
“OpenClaw”是我为本次实战虚构的一个典型企业级SaaS应用场景,它融合了复杂表单、多步骤审批、动态数据表格和第三方集成,非常适合展示AI驱动测试的优势。假设OpenClaw是一个在线采购审批系统,测试场景是:“用户登录后,创建一个新的采购申请,填写复杂的物料清单,提交审批,并验证申请状态在后台列表中正确更新”。
5.1 场景拆解与挑战分析
传统自动化在这个场景下会非常棘手:
- 复杂表单:物料清单是一个动态表格,可以添加/删除行,每行有下拉选择、数字输入、文件上传等多种控件。
- 多页签/模态框:流程涉及多个页面或弹窗,状态管理复杂。
- 异步更新:提交审批后,列表页的状态更新是异步的,需要轮询等待。
- 元素定位脆弱:前端使用React/Vue等框架,生成的DOM元素ID和类名可能动态变化。
AI驱动测试的思路则不同:我们不是去定位“那个ID为item-0-quantity的输入框”,而是告诉AI“在物料表格的第一行,找到数量输入框并填入‘5’”。AI通过视觉和语义来理解界面。
5.2 测试用例设计与实现
我们设计一个端到端的测试用例,并使用之前封装的模式。
# test_openclaw_purchase_request.py import pytest import time from pages.openclaw_login_page import OpenClawLoginPage from pages.openclaw_dashboard_page import OpenClawDashboardPage from pages.openclaw_creation_page import OpenClawPurchaseRequestPage @pytest.mark.e2e @pytest.mark.slow def test_create_and_submit_purchase_request(nova_act): """ 端到端测试:创建并提交采购申请。 验证整个工作流能否被AI正确执行。 """ # 1. 登录 login_page = OpenClawLoginPage(nova_act) dashboard = login_page.login(“test_user”, “password123”) # 返回Dashboard页面对象 allure.attach(“登录成功”, name=”步骤1“, attachment_type=AttachmentType.TEXT) # 2. 导航到创建页面 creation_page = dashboard.navigate_to_create_purchase_request() allure.attach(“已进入采购申请创建页”, name=”步骤2“, attachment_type=AttachmentType.TEXT) # 3. 填写基础信息 - 使用更精确的指令 creation_page.fill_basic_info( title=“Annual Software Subscription”, department=“Engineering”, urgency=“High” ) # fill_basic_info内部可能封装了多个nova.act指令 # 例如:nova.act(“in the ‘Request Title’ field, type ‘Annual Software Subscription’”) # 4. 添加物料行 - 处理动态表格是AI的强项 # 指令可以描述性很强 creation_page.add_line_item( description=“AWS Enterprise Support”, quantity=1, unit_price=10000, cost_center=“CC-123” ) # AI需要:点击“Add Item”,在新行中找到描述、数量、单价、成本中心字段并填写 creation_page.add_line_item( description=“Development Laptops”, quantity=5, unit_price=1500, cost_center=“CC-456” ) # 5. 上传报价单文件 # 注意:文件上传需要特殊处理。AgentCore Browser Tool支持文件上传, # 但需要将文件预先上传到云端或提供可访问的URL。本地文件需通过特定方式传递。 # 假设我们有一个云端临时文件URL quote_url = “https://temp-storage.example.com/quote.pdf” creation_page.upload_quotation(quote_url) # 6. 提交审批 submission_result = creation_page.submit_for_approval() # 这个操作可能会触发模态框、成功提示等。AI需要处理这些交互。 assert “submitted successfully” in submission_result.response.lower() # 7. 验证申请出现在列表中且状态为“Pending” # 返回Dashboard或列表页 list_page = dashboard.navigate_to_my_requests() # 这是一个需要“等待”和“查找”的典型场景 request_found = False for _ in range(10): # 轮询最多10次,每次间隔2秒 search_result = list_page.search_request(“Annual Software Subscription”) if search_result and “Pending” in search_result.status: request_found = True break time.sleep(2) # AI可以执行“refresh the page”或“click next page if not found” list_page.refresh() assert request_found, “新建的申请未在列表中显示或状态不正确” # 8. 可选:以审批者身份登录,进行审批操作(另一个测试用例) # 这展示了如何用同一套框架测试跨角色的完整业务流程。这个测试用例看起来非常直观,就像在描述一个手动测试场景。背后的Page类封装了所有复杂的、描述性的AI指令。
5.3 处理AI的不确定性:重试、降级与断言策略
AI不是100%可靠的。网络波动、页面加载稍慢、UI微小变化都可能导致单次指令失败。因此,我们的测试框架必须具备弹性。
- 指令重试机制:在封装的
act方法中加入重试逻辑。def robust_act(nova_instance, instruction, max_retries=2, delay=2): for attempt in range(max_retries + 1): try: result = nova_instance.act(instruction) if result.response and “error” not in result.response.lower(): # 简单成功判断 return result except Exception as e: print(f”指令执行失败 (尝试 {attempt+1}/{max_retries+1}): {e}“) if attempt < max_retries: time.sleep(delay) print(“重试中...”) raise RuntimeError(f”指令 ‘{instruction}’ 在 {max_retries+1} 次尝试后仍失败”) - 多模态降级策略:如果AI无法通过语义找到“提交按钮”,可以降级使用更明确的指令,比如“点击屏幕上那个蓝色的、写着‘Submit’的按钮”。在极端情况下,甚至可以回退到使用Playwright执行预先定义好的CSS选择器(如果已知)。这需要你在Page Object中设计多套策略。
- 智能断言:不要只断言AI返回的文本完全匹配某个字符串。使用模糊匹配、关键词检查、正则表达式或验证结构化数据中的关键字段。断言的目的应该是验证“业务目标是否达成”,而不是“AI的每一步是否精确按我设想执行”。
5.4 性能与成本考量
AI模型调用和云端浏览器执行都是有成本的(无论是时间还是金钱)。在工程化实践中需要注意:
- 会话复用:对于一组相关的测试用例,考虑使用
scope=”class”或scope=”module”级别的fixture,在一个浏览器会话中顺序执行多个测试,避免频繁启动/关闭浏览器带来的开销。但要注意测试间的状态隔离。 - 指令优化:合并一些简单的、连续的操作到一个
act指令中,减少与AI模型交互的次数。但需平衡指令的复杂度和成功率。 - 并发执行:对于大量独立的测试用例,可以利用pytest-xdist并行运行,同时启动多个AgentCore浏览器会话。需要评估AWS成本与测试提速的收益。
- 监控与告警:记录每个
act的耗时和Token使用情况(如果API提供),设置阈值告警,及时发现异常慢或异常昂贵的测试步骤。
6. 常见问题、调试技巧与未来展望
在实际项目中摸爬滚打几周后,我积累了一些宝贵的“踩坑”经验和调试技巧,这可能是你能找到的最实在的分享。
6.1 典型问题与解决方案速查表
| 问题现象 | 可能原因 | 排查步骤与解决方案 |
|---|---|---|
| 初始化失败,连接被拒绝 | 1. AWS凭证或区域错误。 2. bedrock-agentcore版本与后端不兼容。3. 网络策略限制。 | 1. 检查环境变量AWS_系列或本地~/.aws/credentials。2. 尝试升级/降级 bedrock-agentcore和nova-act到已知稳定的版本。3. 确保运行环境能访问AWS服务端点。 |
nova.act执行超时或无响应 | 1. 指令过于模糊,AI陷入循环。 2. 页面加载太慢,AI在等待。 3. 模型服务暂时不可用。 | 1.开启Browser Viewer,实时观察AI在做什么。这是最重要的调试手段! 2. 简化指令,拆分成更小的步骤。 3. 在指令中增加明确的超时或等待提示,如“wait for the page to load completely then...”。 4. 检查Nova Act API的状态。 |
| AI执行了错误操作 | 1. 页面有多个相似元素,AI选错了。 2. 指令存在歧义。 3. 页面状态并非预期。 | 1. 在Viewer中查看AI点击/输入的位置是否准确。 2.优化指令:提供更精确的上下文。例如,不说“click submit”,而说“in the modal dialog that just appeared, click the blue ‘Submit’ button”。 3. 在执行关键操作前,让AI先“确认”一下页面状态,例如“are you on the checkout page?”。 |
| 无法处理文件上传 | AI模型可能不直接处理本地文件路径。 | 1. 对于AgentCore,通常需要先将文件上传到云存储(如S3),生成一个URL,然后让AI在文件上传输入框中输入该URL。或者,使用Playwright在同一个CDP会话中执行文件上传操作(混合模式)。 2. 参考官方示例,使用 set_input_files方法。 |
| 结构化输出(Schema)不匹配 | AI返回的JSON格式与Schema定义不符。 | 1. 检查schema定义是否准确、完整。2. 在指令中更明确地指定字段。例如,“return a JSON object with exactly two fields: ‘product_name‘ (string) and ’price‘ (string with currency symbol)”。 3. 做好错误处理,当 result.matches_schema为False时,记录result.response进行人工分析,调整指令或Schema。 |
| 测试在CI/CD中不稳定 | 云端环境与本地差异,网络延迟,资源竞争。 | 1.增加等待和重试:在关键断言前加入显式等待(time.sleep或基于条件的等待)。2.使用更稳定的定位策略:虽然AI不依赖传统定位器,但可以引导它使用相对稳定的页面特征,如“the main navigation bar”、“the footer”。 3.配置独立的测试环境,减少与其他人/任务的干扰。 |
6.2 核心调试技巧:像侦探一样观察AI
- Browser Viewer是你的眼睛:任何时候遇到问题,第一反应就是运行带
--headful参数的测试,或者在你的fixture中强制启动Viewer。亲眼看着AI一步步操作,你能立刻明白它卡在了哪里、为什么点错了按钮。 - 利用
ActResult.metadata:这个对象包含了num_steps_executed(执行了多少步)和step_server_times_s(每一步的服务器耗时)。如果步骤数异常多或某一步耗时极长,通常意味着AI遇到了困惑,在反复尝试。 - 日志记录AI的“思考”:Nova Act的底层交互通常会有日志输出(取决于配置)。将这些日志收集起来,和Allure报告关联。你能看到AI内部的推理链,例如:“I see a button that says ‘Submit’. I will click it.” 这对于理解AI的决策过程至关重要。
- 从简单到复杂:不要一开始就测试最复杂的场景。先确保“打开网页 -> 点击链接 -> 返回标题”这样的基础流程能稳定运行。再逐步增加复杂度,如填写表单、处理弹窗、验证动态内容。
6.3 未来展望:AI测试的下一步
当前基于Nova Act的测试,可以看作是“指令跟随型”智能体。它很强,但依然是反应式的。我认为下一步的演进方向是:
- 目标驱动型测试:不再给出一步步的指令,而是给出一个业务目标,如“验证用户可以通过信用卡成功购买最便宜的耳机”。AI需要自己规划从登录、搜索、比价、下单到支付的完整路径,并处理过程中可能出现的各种分支(缺货、地址验证等)。
- 探索性测试智能体:给定一个应用入口,AI像一名好奇的测试员一样,自主探索应用功能,尝试各种输入组合,主动寻找边界情况和潜在缺陷,并生成测试报告。
- 自愈与自适应测试集:当UI发生变更导致一批测试用例失败时,AI不仅能报告失败,还能分析变更(例如通过Diff截图),并自动提议或直接更新相关的测试指令,实现测试套件的“自愈”。
- 与低代码/无代码测试平台集成:将Nova Act这类AI能力作为底层引擎,为上层的可视化拖拽测试设计工具提供智能执行支持,让业务分析师也能轻松创建复杂的端到端测试。
回归到我们测试工程师自身,AI驱动测试的普及,意味着我们的角色必须进化。从“脚本编写与维护者”转向“质量策略设计师”和“AI训练师/调优师”。我们需要更深入地理解业务,设计出更能暴露系统风险的测试场景和目标;我们需要学会如何与AI协作,编写有效的指令,解读AI的行为,并构建一套稳固的工程体系来管理这些“智能”测试资产。这个过程充满挑战,但也让我们从重复劳动中解脱,去解决更有价值的问题。这场变革已经到来,而亲手将Nova Act、AgentCore和pytest组合起来,解决像OpenClaw这样的真实难题,正是我们拥抱它的最佳方式。