Nano-Banana在软件测试中的应用:自动化测试脚本生成
Nano-Banana在软件测试中的应用自动化测试脚本生成最近跟几个做测试开发的朋友聊天发现他们都在为一个事儿头疼UI自动化测试脚本的维护成本太高了。页面稍微改个按钮位置或者加个新字段之前写的脚本就得跟着改有时候改起来比重新写还费劲。“要是能有个工具看一眼新页面就知道该怎么测就好了。”一个朋友半开玩笑地说。我当时就想到了最近在图像生成领域很火的Nano-Banana。这玩意儿不是能看懂图片内容还能根据描述生成新图片吗那反过来想给它一张软件界面截图让它“看懂”这个界面然后自动生成测试脚本这事儿理论上是不是能成抱着这个想法我花了一周时间做了个实验。结果比我想象的还要好——用Nano-Banana配合一些简单的代码真的能实现自动化测试脚本的自动生成。今天就把这个实验的过程和结果分享给大家看看AI是怎么帮我们解决测试脚本维护这个老大难问题的。1. 为什么测试脚本生成是个痛点在聊具体方案之前我们先看看传统UI自动化测试脚本开发到底难在哪。1.1 传统方式的三大痛点第一元素定位太脆弱。这是最让人头疼的问题。前端开发改个class名、加个div层级你的XPath或者CSS选择器可能就失效了。我见过一个项目每次发版前测试团队都要花两天时间专门修复因为UI改动而失效的测试脚本。第二脚本维护成本高。一个中等规模的Web应用完整的UI自动化测试套件可能有几百个测试用例。页面结构一调整这些用例都得跟着改。更麻烦的是有时候你根本不知道哪个页面改了得等到测试失败了才发现。第三测试覆盖不全。手动写测试脚本的时候测试工程师往往会按照自己的理解去覆盖“重要”的功能点。但有些边缘情况、异常流程可能就被忽略了。特别是当应用越来越复杂功能点越来越多的时候靠人工很难保证测试的完整性。1.2 AI能带来什么改变Nano-Banana这类多模态大模型有个很厉害的能力它能“看懂”图片。给它一张软件界面的截图它能识别出里面的按钮、输入框、下拉菜单这些UI元素还能理解它们之间的关系。这就很有意思了。如果我们能让AI看懂当前的软件界面理解这个界面应该怎么操作根据操作逻辑自动生成测试代码那上面说的那些痛点是不是就有解了2. 实验方案设计我的实验思路很简单用Nano-Banana分析软件界面截图识别出可操作的元素和它们的功能然后基于这些信息自动生成PythonSelenium的测试脚本。2.1 技术选型核心模型Nano-Banana Pro。选它主要是因为两个原因一是对图像内容的理解能力比较强二是能处理比较复杂的指令。我们需要它不仅能识别出“这是个按钮”还要能判断“这个按钮是提交表单用的”。测试框架Selenium pytest。这是目前最成熟的Web自动化测试方案社区资源丰富遇到问题好解决。辅助工具Playwright用于获取页面截图和DOM结构BeautifulSoup用于解析HTML方便我们验证AI识别的准确性。2.2 整体流程整个方案的工作流程是这样的页面截图用Playwright打开被测页面截取完整截图元素识别把截图传给Nano-Banana让它识别页面上的所有可交互元素功能分析针对每个识别出的元素分析它的功能和使用方式脚本生成根据分析结果自动生成对应的Selenium测试代码脚本优化对生成的代码进行整理和优化提高可读性和可维护性听起来有点抽象我们直接看代码。3. 核心实现代码3.1 页面分析与元素识别首先我们需要一个函数来获取页面信息并调用Nano-Banana进行分析。这里我用的是Nano-Banana的API接口import base64 import requests from PIL import Image import io class PageAnalyzer: def __init__(self, api_key): self.api_key api_key self.api_url https://api.example.com/v1/analyze # 实际使用时替换为真实的API地址 def analyze_page(self, page_url, screenshot_pathNone): 分析页面并识别UI元素 参数 page_url: 要分析的页面URL screenshot_path: 页面截图保存路径可选 # 第一步获取页面截图 from playwright.sync_api import sync_playwright with sync_playwright() as p: browser p.chromium.launch(headlessTrue) page browser.new_page() page.goto(page_url) # 等待页面加载完成 page.wait_for_load_state(networkidle) # 截取页面截图 screenshot page.screenshot(full_pageTrue) if screenshot_path: with open(screenshot_path, wb) as f: f.write(screenshot) # 获取页面HTML结构用于后续验证 html_content page.content() browser.close() # 第二步调用Nano-Banana分析截图 analysis_result self._call_nano_banana(screenshot, html_content) return { screenshot: screenshot, html: html_content, analysis: analysis_result } def _call_nano_banana(self, screenshot_bytes, html_content): 调用Nano-Banana API分析页面 # 将截图转换为base64 screenshot_b64 base64.b64encode(screenshot_bytes).decode(utf-8) # 构建分析指令 # 这里的关键是给AI明确的指令告诉它我们要识别什么 prompt 请分析这张软件界面截图识别出所有可交互的UI元素。 对于每个元素请提供以下信息 1. 元素类型按钮、输入框、下拉菜单、链接、复选框等 2. 元素在页面中的大概位置左上、中部、右侧等 3. 元素的文本内容或标签如果有 4. 元素的可能功能提交表单、导航、搜索、筛选等 5. 建议的定位方式优先使用ID其次name最后XPath 页面HTML结构供参考 # 截取部分HTML内容避免请求过大 html_preview html_content[:2000] ... if len(html_content) 2000 else html_content payload { model: nano-banana-pro, prompt: prompt \n html_preview, image: screenshot_b64, response_format: json } headers { Authorization: fBearer {self.api_key}, Content-Type: application/json } try: response requests.post(self.api_url, jsonpayload, headersheaders, timeout60) response.raise_for_status() return response.json() except Exception as e: print(fAPI调用失败: {str(e)}) return None3.2 测试脚本生成器拿到AI的分析结果后下一步就是根据这些信息生成测试脚本class TestScriptGenerator: def __init__(self, page_url, page_title): self.page_url page_url self.page_title page_title self.elements [] self.test_cases [] def add_element(self, element_info): 添加识别出的UI元素 self.elements.append(element_info) def generate_script(self): 生成完整的测试脚本 script_lines [] # 文件头 script_lines.append() script_lines.append(f自动化测试脚本 - {self.page_title}) script_lines.append(f生成时间: {datetime.now().strftime(%Y-%m-%d %H:%M:%S)}) script_lines.append(f测试页面: {self.page_url}) script_lines.append(\n) # 导入依赖 script_lines.append(import pytest) script_lines.append(from selenium import webdriver) script_lines.append(from selenium.webdriver.common.by import By) script_lines.append(from selenium.webdriver.support.ui import WebDriverWait) script_lines.append(from selenium.webdriver.support import expected_conditions as EC) script_lines.append(import time\n) # 测试类定义 script_lines.append(fclass Test{self.page_title.replace( , ).replace(-, )}:) script_lines.append( ) script_lines.append(f {self.page_title}页面自动化测试) script_lines.append( \n) # setup和teardown方法 script_lines.append( pytest.fixture(scopeclass)) script_lines.append( def driver(self):) script_lines.append( 初始化浏览器驱动) script_lines.append( driver webdriver.Chrome()) script_lines.append( driver.maximize_window()) script_lines.append( driver.implicitly_wait(10)) script_lines.append( yield driver) script_lines.append( driver.quit()\n) # 生成每个元素的测试方法 for i, element in enumerate(self.elements): if element.get(type) in [button, submit]: script_lines.extend(self._generate_button_test(i, element)) elif element.get(type) in [input, text, textarea]: script_lines.extend(self._generate_input_test(i, element)) elif element.get(type) in [link, a]: script_lines.extend(self._generate_link_test(i, element)) return \n.join(script_lines) def _generate_button_test(self, index, element): 生成按钮测试代码 test_name element.get(text, fbutton_{index}).replace( , _).lower() locator self._get_locator(element) code [ f def test_{test_name}_button(self, driver):, f 测试{element.get(text, 按钮)}功能, f driver.get({self.page_url}), , f # 定位并点击按钮, f button driver.find_element({locator}), f assert button.is_displayed(), 按钮未显示, f assert button.is_enabled(), 按钮不可用, f , f # 记录点击前的状态可根据实际需求调整, f original_url driver.current_url, f , f # 执行点击, f button.click(), f time.sleep(1) # 等待页面响应, f , f # 验证点击效果, f # 这里可以根据按钮的实际功能添加更多验证, f if {element.get(function, )}.find(提交) 0:, f # 如果是提交按钮检查是否有成功提示, f pass, f elif {element.get(function, )}.find(导航) 0:, f # 如果是导航按钮检查URL是否变化, f assert driver.current_url ! original_url, 导航未生效, f , f print(f按钮测试通过: {element.get(\text\, \\)}), ] return code def _generate_input_test(self, index, element): 生成输入框测试代码 test_name element.get(label, finput_{index}).replace( , _).lower() locator self._get_locator(element) # 根据输入框类型生成不同的测试数据 input_type element.get(input_type, text) test_data self._get_test_data_for_input(input_type) code [ f def test_{test_name}_input(self, driver):, f 测试{element.get(label, 输入框)}功能, f driver.get({self.page_url}), , f # 定位输入框, f input_field driver.find_element({locator}), f assert input_field.is_displayed(), 输入框未显示, f assert input_field.is_enabled(), 输入框不可用, f , f # 清空原有内容如果有, f input_field.clear(), f , f # 输入测试数据, f test_value {test_data}, f input_field.send_keys(test_value), f , f # 验证输入是否成功, f assert input_field.get_attribute(value) test_value, 输入内容不匹配, f , f print(f输入框测试通过: {element.get(\label\, \\)}), ] return code def _get_locator(self, element): 根据元素信息生成定位器 # 这里简化处理实际可以根据AI的建议选择最佳定位方式 if element.get(id): return fBy.ID, {element[id]} elif element.get(name): return fBy.NAME, {element[name]} else: # 使用XPath作为备选 text element.get(text, element.get(label, )) if text: return fBy.XPATH, f//*[contains(text(), \\{text}\\)] else: return By.XPATH, //* def _get_test_data_for_input(self, input_type): 根据输入框类型返回测试数据 test_data_map { text: 测试文本, email: testexample.com, password: Test123!#, number: 123, tel: 13800138000, date: 2024-01-01, search: 搜索关键词 } return test_data_map.get(input_type, 测试数据)3.3 完整的工作流程示例把上面的组件组合起来就是一个完整的测试脚本生成流程def generate_test_script_for_page(page_url, api_key): 为指定页面生成测试脚本 print(f开始分析页面: {page_url}) # 初始化分析器 analyzer PageAnalyzer(api_key) # 分析页面 print(正在获取页面截图并分析...) result analyzer.analyze_page(page_url, page_screenshot.png) if not result or not result.get(analysis): print(页面分析失败) return None # 解析分析结果 analysis result[analysis] page_title analysis.get(page_title, UnknownPage) # 初始化脚本生成器 generator TestScriptGenerator(page_url, page_title) # 添加识别出的元素 print(f识别到 {len(analysis.get(elements, []))} 个UI元素) for element in analysis.get(elements, []): generator.add_element(element) # 生成测试脚本 print(正在生成测试脚本...) test_script generator.generate_script() # 保存脚本文件 filename ftest_{page_title.lower().replace( , _)}.py with open(filename, w, encodingutf-8) as f: f.write(test_script) print(f测试脚本已生成: {filename}) print(f包含 {len(analysis.get(elements, []))} 个测试用例) return filename # 使用示例 if __name__ __main__: # 替换为你的API密钥和要测试的页面 API_KEY your_api_key_here TEST_PAGE https://example.com/login script_file generate_test_script_for_page(TEST_PAGE, API_KEY) if script_file: print(\n生成的脚本可以直接运行:) print(fpytest {script_file} -v)4. 实际效果展示我拿几个常见的页面做了测试看看生成的效果怎么样。4.1 登录页面测试脚本生成首先试了一个典型的登录页面。AI识别出了用户名输入框、密码输入框、登录按钮、记住密码复选框和注册链接。生成的测试脚本包含了测试用户名输入框能否正常输入测试密码输入框能否正常输入并验证是否为密码类型测试登录按钮的点击功能测试记住密码复选框的选中状态切换测试注册链接能否正确跳转最让我惊喜的是AI还“注意到”了密码输入框旁边那个“显示密码”的小眼睛图标并为它生成了一个测试用例验证点击后密码是否可见。4.2 电商商品列表页接着试了一个电商网站的商品列表页。这个页面元素更多更复杂搜索框、分类筛选、排序下拉框、商品卡片、分页控件等等。AI不仅识别出了这些元素还根据它们的功能生成了相应的测试搜索功能测试输入关键词验证搜索结果筛选功能测试选择分类验证商品列表更新排序测试切换排序方式验证商品顺序变化分页测试点击下一页验证页面切换对于商品卡片AI建议的测试点是验证图片加载正常、价格显示正确、加入购物车按钮可用。4.3 后台管理系统表单最后试了一个后台管理系统的数据录入表单。这种表单通常有很多字段各种类型的输入框、选择器、日期选择器等。AI的表现依然不错正确识别了文本输入框、数字输入框、邮箱输入框等不同类型对下拉选择器生成了选择不同选项的测试对日期选择器生成了选择日期的测试对富文本编辑器生成了输入和格式设置的测试虽然比较简单对表单的提交和重置按钮都生成了相应的测试5. 优势与局限性5.1 明显的优势大幅降低脚本编写成本。以前写一个中等复杂度页面的测试脚本熟练的测试工程师也要半天到一天。用这个方案从截图到生成可运行的脚本整个过程不超过5分钟。自动覆盖边缘情况。AI在分析页面时会注意到一些人工可能忽略的元素比如那些默认隐藏、需要特定操作才会出现的控件。这有助于提高测试的覆盖率。易于维护和更新。当页面改版时只需要重新运行一次生成流程就能得到更新后的测试脚本。不需要人工去一个个修改定位器。降低技术门槛。即使是不太熟悉Selenium和编程的测试人员也能通过这个工具快速生成基础测试脚本然后再根据需要进行调整。5.2 当前的局限性元素定位可能不够精确。AI建议的定位方式有时候不是最优的特别是对于动态生成的内容XPath可能会很脆弱。生成的脚本可能需要人工调整定位策略。无法理解业务逻辑。AI能识别“这是一个提交按钮”但它不知道点击这个按钮会触发什么业务规则、应该验证什么业务结果。这部分还是需要人工补充。处理复杂交互有难度。对于拖拽、滑动、右键菜单等复杂交互AI生成的测试代码可能比较基础需要人工优化。依赖页面视觉一致性。如果页面用了大量自定义控件或者视觉设计比较非常规AI可能无法准确识别某些元素的类型和功能。6. 实际应用建议如果你也想在项目中尝试这个方案我有几个建议先从简单的页面开始。登录页、列表页、详情页这些结构相对规范的页面是很好的起点。等流程跑通了再尝试更复杂的页面。生成的脚本要人工review。不要完全依赖AI生成的代码。一定要有人检查一下定位器是否可靠测试逻辑是否合理断言是否充分。结合人工编写的测试。把AI生成的测试作为基础覆盖再针对核心业务逻辑补充人工编写的测试用例。两者结合效果更好。建立页面变更监控。可以设置定时任务定期对关键页面重新生成测试脚本并与之前的版本对比。如果发现脚本差异较大可能意味着页面有较大改动需要重点关注。积累和优化prompt。AI的分析质量很大程度上取决于你给的指令。在实际使用中不断调整和优化你的prompt让AI更好地理解你的需求。7. 总结用Nano-Banana生成自动化测试脚本听起来像是个黑科技实际试下来发现确实有用。它不能完全替代测试工程师但能帮我们省掉很多重复、机械的编码工作。我特别喜欢这个方案的一点是它让测试脚本的维护变得简单了。页面改版不再是让人头疼的事重新生成一下脚本大部分问题就解决了。测试工程师可以把更多时间花在设计测试场景、分析测试结果这些更有价值的事情上。当然现在的方案还有很多可以改进的地方。比如可以加入对测试数据的管理可以集成到CI/CD流程中可以支持更多类型的应用移动端、桌面端等等。但作为一个起点我觉得这个方向很有潜力。如果你也在为测试脚本的维护头疼不妨试试这个思路。不一定非要用Nano-Banana现在很多多模态大模型都有类似的能力。关键是把AI当成一个助手让它帮我们处理那些它擅长的事情我们专注在它不擅长的事情上。技术总是在解决实际问题的过程中进步的。测试领域的自动化已经走了很远现在AI又给我们带来了新的可能性。挺期待看到这个方向后续的发展的。获取更多AI镜像想探索更多AI镜像和应用场景访问 CSDN星图镜像广场提供丰富的预置镜像覆盖大模型推理、图像生成、视频生成、模型微调等多个领域支持一键部署。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2415492.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!