news 2026/2/26 0:21:35

MAI-UI-8B Web自动化测试:从入门到精通

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
MAI-UI-8B Web自动化测试:从入门到精通

MAI-UI-8B Web自动化测试:从入门到精通

你是不是也遇到过这样的场景?每天要花大量时间在网页上重复点击、填写表单、验证结果,这些操作枯燥又容易出错。或者,你的产品上线前需要做大量的回归测试,手动操作不仅效率低,还常常因为疲劳导致漏测。

传统的自动化测试工具,比如Selenium,虽然功能强大,但写起脚本来一点也不轻松。你得精确地定位每个按钮、输入框的XPath或CSS选择器,页面稍微改个样式,脚本可能就全废了。维护成本高得让人头疼。

现在,情况有点不一样了。最近阿里通义实验室开源了一个叫MAI-UI-8B的模型,它本质上是一个能“看懂”屏幕并“动手”操作的GUI智能体。虽然它最初的设计目标是操作手机App,但其强大的视觉理解和元素定位能力,让它天然地非常适合用来做Web自动化测试。

这篇文章,我就带你从零开始,看看怎么用MAI-UI-8B来玩转Web自动化测试。咱们不搞那些复杂的理论,直接上手,从环境搭建到写第一个测试脚本,再到处理实际项目中那些棘手的场景,一步步来。你会发现,用“AI眼睛”来做测试,思路完全不一样了。

1. 为什么选择MAI-UI-8B做Web测试?

在跳进代码之前,咱们先聊聊为什么是它。市面上自动化测试工具那么多,MAI-UI-8B有什么特别的?

首先,它最大的优势是“视觉驱动”。你不需要再去费劲地研究页面的DOM结构,找那些长得像//div[@id='root']/div[3]/button[2]的复杂定位符。你只需要告诉模型:“点击那个蓝色的‘提交’按钮”,或者“在‘用户名’输入框里填上‘test_user’”。模型自己会去看屏幕截图,找到对应的元素并操作。这大大降低了编写和维护脚本的门槛。

其次,它非常健壮。网页UI经常变,今天按钮是蓝色,明天可能改成绿色;今天叫“提交”,明天可能叫“确认”。用传统方法,这种改动就是测试脚本的灾难。但MAI-UI-8B基于视觉和语义理解,只要按钮的功能和位置大致没变,它就能认出来,适应性更强。

最后,它能处理一些模糊指令。比如你说“勾选所有选项”,它能理解并找到页面上所有的复选框。这在处理动态生成、数量不定的元素时特别有用。

当然,它也不是万能的。纯视觉操作在速度上可能比不上直接操作DOM的脚本,对于极度复杂的动态效果或需要像素级精确的操作,也可能有挑战。但对于大多数功能测试、回归测试场景,它已经是一个革命性的工具了。

2. 快速搭建你的测试环境

好了,理论说完,咱们动手。要玩转MAI-UI-8B,你得先把它跑起来。别担心,步骤不算复杂。

2.1 基础环境准备

首先,确保你的机器有Python环境(建议3.9以上),最好还有一个不算太差的GPU(比如NVIDIA GTX 1060 6G或以上),这样模型推理速度会快很多。纯CPU也能跑,就是会慢一些。

打开你的终端,我们一步步来。

# 1. 把MAI-UI的代码仓库克隆到本地 git clone https://github.com/Tongyi-MAI/MAI-UI.git cd MAI-UI # 2. 安装项目依赖 pip install -r requirements.txt

2.2 启动模型API服务

MAI-UI-8B模型本身比较大,我们需要一个服务来加载它并提供API。这里用vLLM来部署,这是目前高性能推理常用的工具。

# 安装vLLM pip install vllm # 启动API服务。如果你没有提前下载模型,这里指定HuggingFace的模型ID,它会自动下载。 # 注意:这步需要较好的网络环境和足够的磁盘空间(模型约16GB)。 python -m vllm.entrypoints.openai.api_server \ --model Tongyi-MAI/MAI-UI-8B \ --served-model-name MAI-UI-8B \ --host 0.0.0.0 \ --port 8000 \ --tensor-parallel-size 1 \ --trust-remote-code

参数简单解释一下:

  • --model: 指定模型路径,这里直接用HuggingFace的ID。
  • --served-model-name: 给你的服务起个名字,后面调用API时用。
  • --host--port: 服务监听的地址和端口,默认localhost:8000就行。
  • --tensor-parallel-size: 如果你有多张GPU,可以设置大于1来加速。一张GPU就设为1。

命令执行后,你会看到一堆日志输出。等到出现类似“Uvicorn running on ...”的提示,就说明服务启动成功了。这个服务提供了一个OpenAI兼容的API端点,地址是http://localhost:8000/v1

让这个终端窗口保持运行,我们另开一个终端进行下一步。

2.3 安装Web自动化测试“手脚”

模型有了“大脑”和“眼睛”,我们还需要给它配上能在浏览器里操作的“手”。这里我们用playwright,一个非常现代的浏览器自动化库。

# 安装playwright以及它对应的浏览器驱动 pip install playwright playwright install chromium # 我们以Chromium浏览器为例

好了,环境齐活!接下来,我们就要写代码,让MAI-UI-8B这个“大脑”通过playwright这个“手”来操作浏览器了。

3. 你的第一个视觉自动化测试脚本

我们现在来写一个最简单的测试脚本:打开百度首页,在搜索框输入“MAI-UI”,然后点击搜索按钮。

传统的Playwright脚本需要你写选择器。今天,我们换个写法。

创建一个新的Python文件,比如叫first_web_test.py

import asyncio import base64 from io import BytesIO from openai import OpenAI from playwright.async_api import async_playwright # 1. 初始化MAI-UI客户端(指向我们刚启动的本地服务) client = OpenAI( base_url="http://localhost:8000/v1", api_key="no-key-required" # 本地服务不需要key ) # 2. 定义核心函数:让MAI-UI分析屏幕并决定下一步操作 async def ask_mai_ui_for_action(screenshot_b64, user_instruction, history=[]): """ screenshot_b64: 网页截图的base64编码 user_instruction: 你给模型的指令,比如“点击搜索按钮” history: 对话历史,让模型知道之前做了什么 """ # 构建消息。MAI-UI-8B是多模态模型,可以接收图片。 messages = history + [ { "role": "user", "content": [ {"type": "text", "text": user_instruction}, { "type": "image_url", "image_url": { "url": f"data:image/jpeg;base64,{screenshot_b64}" } } ] } ] try: response = client.chat.completions.create( model="MAI-UI-8B", messages=messages, max_tokens=500, temperature=0.0 # 测试任务,我们希望决策稳定,所以温度设为0 ) # 模型的回复里包含了它的“思考”和“动作” model_reply = response.choices[0].message.content return model_reply except Exception as e: print(f"调用MAI-UI API出错: {e}") return None # 3. 主测试逻辑 async def main(): # 启动Playwright和浏览器 async with async_playwright() as p: # 用Chromium启动一个非无头模式浏览器,这样我们能看见过程 browser = await p.chromium.launch(headless=False) page = await browser.new_page() # 第一步:导航到百度 await page.goto("https://www.baidu.com") print("已打开百度首页") await page.wait_for_timeout(2000) # 等待2秒让页面加载完全 # 第二步:让MAI-UI帮我们在搜索框输入文字 # 先截个图 screenshot = await page.screenshot() screenshot_b64 = base64.b64encode(screenshot).decode('utf-8') # 给模型下指令 instruction = "在页面的主要搜索输入框内,输入文字:MAI-UI" print(f"指令: {instruction}") reply = await ask_mai_ui_for_action(screenshot_b64, instruction) print(f"模型回复: {reply}") # 注意:模型回复是文本,描述了它想做的动作。 # 在一个完整的Agent系统里,这里会解析回复,提取出具体的坐标或元素信息,然后让Playwright去执行。 # 为了简化,我们这里先手动模拟一下模型“成功找到并输入”的动作。 # 实际上,你需要根据模型回复来执行操作,这涉及到动作解析,是另一个有趣的话题。 # 这里我们直接使用Playwright的定位方式来完成输入,以示流程。 await page.locator("input#kw").fill("MAI-UI") print("已在搜索框输入‘MAI-UI’") await page.wait_for_timeout(1000) # 第三步:让MAI-UI点击“百度一下”按钮 screenshot = await page.screenshot() screenshot_b64 = base64.b64encode(screenshot).decode('utf-8') instruction = "点击‘百度一下’按钮进行搜索" print(f"指令: {instruction}") reply = await ask_mai_ui_for_action(screenshot_b64, instruction) print(f"模型回复: {reply}") # 同样,我们模拟执行点击 await page.locator("input#su").click() print("已点击‘百度一下’按钮") # 等待搜索结果加载 await page.wait_for_timeout(3000) # 可以再加一步,验证搜索结果页面是否包含相关文本 content = await page.content() if "MAI-UI" in content: print("测试通过!搜索结果页面包含‘MAI-UI’。") else: print("测试未发现预期文本。") # 稍作停留后关闭浏览器 await page.wait_for_timeout(2000) await browser.close() # 运行异步主函数 if __name__ == "__main__": asyncio.run(main())

把上面的代码保存并运行。你会看到一个浏览器窗口自动打开,访问百度,输入文字并点击搜索。

这个脚本的关键点在于:

  1. 流程:打开页面 -> 截图 -> 把截图和指令发给MAI-UI -> 获取模型决策 -> 执行决策。
  2. 当前局限:我们的脚本里,执行动作(输入、点击)还是用传统的Playwright选择器(input#kw)来完成的。这是因为模型返回的是自然语言描述,我们需要一个额外的“解析层”把它转换成浏览器能执行的具体命令(比如坐标点击、键盘输入)。构建这个解析层是整合视觉模型与自动化工具的核心,我们稍后会讨论。
  3. 演示价值:即使动作执行是模拟的,这个流程也清晰地展示了如何将MAI-UI的视觉理解能力嵌入到Web自动化流程中。模型在收到“点击‘百度一下’按钮”的指令后,如果能准确定位到那个按钮,就证明了其能力。

4. 处理真实世界的复杂场景

简单的例子跑通了,但真实项目里的网页可没这么友好。弹窗、动态加载、iframe、验证码……各种坑。我们看看MAI-UI-8B怎么应对。

4.1 处理弹窗和动态内容

很多网页操作后会弹出确认框、提示框。传统脚本需要预先写好处理这些弹窗的逻辑。用MAI-UI,我们可以用一种更“鲁棒”的方式。

思路是:每一步操作后,都检查一下屏幕状态,如果出现了非预期的元素(比如弹窗),就让模型去处理它。

我们修改一下主逻辑,加入一个简单的状态检查循环:

async def execute_instruction_with_retry(page, instruction, max_retries=3): """执行一个指令,并处理可能出现的中间状态(如弹窗)""" for attempt in range(max_retries): # 1. 截图,问模型 screenshot = await page.screenshot() screenshot_b64 = base64.b64encode(screenshot).decode('utf-8') reply = await ask_mai_ui_for_action(screenshot_b64, instruction) # 2. 解析模型回复(这里简化,假设回复是JSON格式的动作描述) # 例如:{"action": "click", "description": "蓝色的确认按钮"} # 我们需要一个函数 parse_action(reply) 来提取动作类型和定位信息。 action = parse_action(reply) # 3. 执行动作(这里用伪代码表示) if action["type"] == "click": # 根据action['description']或action['bbox'](边界框)来让Playwright点击 await click_element_by_description(page, action["description"]) elif action["type"] == "type": await type_text_by_description(page, action["description"], action["text"]) # ... 其他动作类型 # 4. 等待一小会儿,然后检查页面是否“稳定”(比如没有新的主要弹窗出现) await page.wait_for_timeout(1000) new_screenshot = await page.screenshot() # 简单比较截图哈希,判断页面是否大幅变化。实际应用中可能需要更复杂的判断。 if not page_changed_significantly(screenshot, new_screenshot): print(f"指令‘{instruction}’执行成功,页面已稳定。") return True else: print(f"第{attempt+1}次尝试后页面状态变化,可能出现了弹窗或跳转,准备重试或处理...") # 可以在这里插入一个处理异常状态的子指令,比如“关闭任何弹窗” instruction = "如果当前有弹窗、提示框或广告,请关闭它。" print(f"指令‘{instruction}’在{max_retries}次尝试后仍未成功。") return False

这个execute_instruction_with_retry函数提供了一个框架,让自动化流程具备了基本的容错和自适应能力。MAI-UI的视觉能力让它能识别出“弹窗”这种视觉模式,从而执行“关闭”操作,而不需要你提前知道弹窗的具体选择器。

4.2 测试数据驱动与断言验证

自动化测试不仅仅是操作,更重要的是验证结果。MAI-UI同样可以帮我们做“视觉断言”和“语义断言”。

  • 视觉断言:比如,提交订单后,截图让模型判断“页面上是否出现了‘订单提交成功’的字样”。这比用page.locator("text=订单提交成功")更灵活,因为文字样式、位置可能变化,但语义不变。
  • 语义断言:比如,在商品列表页,让模型“数一数当前页面显示了多少个商品卡片”,或者“找出所有价格低于100元的商品”。这些用纯DOM操作很难写,但用视觉模型结合语言理解,就相对直观。
async def visual_assertion(page, assertion_instruction): """使用MAI-UI进行视觉断言""" screenshot = await page.screenshot() screenshot_b64 = base64.b64encode(screenshot).decode('utf-8') # 指令可以是:“页面上是否显示‘登录成功’的提示?” reply = await ask_mai_ui_for_action(screenshot_b64, assertion_instruction) # 解析模型的回答,通常是“是/否”或一段描述 if "是" in reply or "存在" in reply or "true" in reply.lower(): return True else: print(f"断言失败。模型回复: {reply}") return False # 在测试中使用 # await visual_assertion(page, “当前页面是否包含‘支付成功’的提示信息?”)

5. 进阶技巧:从演示到可维护的测试框架

我们上面写的例子比较零散。要真正用在项目中,需要一些工程化的考虑。

5.1 动作解析与执行器

这是连接MAI-UI“大脑”和Playwright“手脚”的关键桥梁。模型返回的自然语言需要被解析成结构化数据。MAI-UI项目本身提供了一些基础,但针对Web测试,我们可以定义自己的动作协议。

# 一个简单的动作协议定义 ACTION_PROTOCOL = { "click": {"params": ["description", "bbox"]}, "type": {"params": ["description", "bbox", "text"]}, "scroll": {"params": ["direction", "amount"]}, "wait": {"params": ["condition"]}, } def parse_model_reply_to_action(reply_text): """ 一个非常简单的解析器示例。 实际应用中,你可能需要训练一个小的文本分类/信息提取模型, 或者要求MAI-UI以严格的JSON格式输出。 """ action = {} reply_lower = reply_text.lower() if "click" in reply_lower: action["type"] = "click" # 这里可以尝试用NER提取描述,例如“蓝色的提交按钮” # 简化处理,我们假设描述在引号里 import re matches = re.findall(r'["\'](.*?)["\']', reply_text) if matches: action["description"] = matches[-1] elif "type" in reply_lower or "input" in reply_lower: action["type"] = "type" # 提取要输入的文本 # ... 解析逻辑 elif "scroll" in reply_lower: action["type"] = "scroll" # ... 解析逻辑 else: action["type"] = "unknown" action["raw_reply"] = reply_text return action

有了解析后的动作,再写一个执行器,调用Playwright的API去完成具体操作。这部分需要精细设计,比如如何根据descriptionbbox(边界框坐标)找到并操作元素。

5.2 测试用例的抽象与封装

不要在每个测试脚本里都写一遍启动服务、初始化浏览器、执行指令的流程。应该封装一个基础的测试类。

class MAIUIWebTester: def __init__(self, headless=False): self.client = OpenAI(base_url="http://localhost:8000/v1", api_key="no-key") self.headless = headless self.browser = None self.page = None async def __aenter__(self): self.playwright = await async_playwright().start() self.browser = await self.playwright.chromium.launch(headless=self.headless) self.page = await self.browser.new_page() return self async def __aexit__(self, exc_type, exc_val, exc_tb): await self.browser.close() await self.playwright.stop() async def run_test_step(self, instruction, max_retries=3): # 封装了重试和异常处理的指令执行逻辑 # ... pass async def assert_visual(self, assertion_text): # 封装视觉断言 # ... pass # 使用示例 async def test_login(): async with MAIUIWebTester(headless=False) as tester: await tester.page.goto("https://example.com/login") await tester.run_test_step("在用户名输入框中输入‘admin’") await tester.run_test_step("在密码输入框中输入‘123456’") await tester.run_test_step("点击登录按钮") await tester.page.wait_for_timeout(2000) result = await tester.assert_visual(“页面是否显示‘欢迎,admin’的问候语?”) assert result, "登录后欢迎语断言失败"

这样,写新的测试用例就变得非常清晰和简洁,更像是在描述测试场景,而不是在编写复杂的自动化脚本。

6. 总结

走完这一趟,你应该对用MAI-UI-8B做Web自动化测试有了一个从概念到实践的认识。它确实打开了一扇新的大门,让我们可以用更接近人类的方式与网页交互,从而编写出更健壮、更容易维护的自动化测试。

它的核心优势在于降低了自动化脚本的编写和维护成本,特别是对于UI频繁变动、或者需要处理大量非结构化元素验证的场景。当然,目前这套方法还在探索阶段,动作解析的精度、执行速度、以及复杂交互(如拖拽、画图)的处理,都是需要继续研究和优化的地方。

但无论如何,这代表了一个趋势:AI正在从“生成内容”走向“操作世界”。对于测试工程师来说,拥抱这种变化,学习如何利用AI视觉模型来增强现有的自动化框架,无疑是一个值得投入的方向。你不一定要完全替换掉Selenium或Playwright,但可以把MAI-UI这样的模型作为它们的“智能增强插件”,在那些传统方法吃力不讨好的地方,让它大显身手。

下次当你面对一个满是动态元素、选择器变幻莫测的网页时,不妨想想:“能不能让AI帮我看一眼?” 也许,答案就在这里。


获取更多AI镜像

想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/2/25 20:55:42

Flowise安全配置:环境变量加密与API访问权限控制

Flowise安全配置:环境变量加密与API访问权限控制 1. Flowise是什么:拖拽式AI工作流的“乐高积木” Flowise 是一个真正让普通人也能玩转大模型应用的开源平台。它不像传统LangChain开发那样需要写几十行代码、配置一堆依赖,而是把LLM调用、…

作者头像 李华
网站建设 2026/2/26 5:31:47

如何利用AdvancedSessionsPlugin提升多人游戏开发中的会话管理效率

如何利用AdvancedSessionsPlugin提升多人游戏开发中的会话管理效率 【免费下载链接】AdvancedSessionsPlugin Advanced Sessions Plugin for UE4 项目地址: https://gitcode.com/gh_mirrors/ad/AdvancedSessionsPlugin AdvancedSessionsPlugin是一款针对UE4开发的开源会…

作者头像 李华
网站建设 2026/2/24 13:00:03

SmolVLA开源大模型部署:lerobot[smolvla]>=0.4.4依赖精准安装指南

SmolVLA开源大模型部署:lerobot[smolvla]>0.4.4依赖精准安装指南 1. 项目概述 SmolVLA是一个专为经济型机器人设计的紧凑型视觉-语言-动作(VLA)模型。这个开源项目通过Web界面提供了直观的交互式推理演示,让开发者能够快速体验模型能力。 核心特点…

作者头像 李华
网站建设 2026/2/26 9:53:40

一键部署GME多模态模型:解锁Any2Any搜索新技能

一键部署GME多模态模型:解锁Any2Any搜索新技能 1. 什么是GME?一个真正能“看懂又读懂”的多模态向量模型 你有没有遇到过这样的场景: 看到一张设计精美的海报,想立刻找到同风格的配图素材,却只能靠关键词硬猜&#…

作者头像 李华
网站建设 2026/2/24 23:52:10

BGE-Large-Zh在智能客服中的应用:快速实现多轮对话语义匹配

BGE-Large-Zh在智能客服中的应用:快速实现多轮对话语义匹配 1. 为什么智能客服需要真正的语义理解能力 你有没有遇到过这样的客服对话? 用户问:“我上个月买的耳机充不进电,包装盒还在,能换吗?” 系统却返…

作者头像 李华
网站建设 2026/2/18 5:28:39

开箱即用!WeKnora知识库问答系统快速体验

开箱即用!WeKnora知识库问答系统快速体验 无需配置、不装依赖、不写代码——粘贴一段文字,立刻获得精准答案。这不是演示,是真实可用的“知识即服务”。 你是否经历过这些场景: 会议刚结束,几十页纪要还没消化&#x…

作者头像 李华