来源:得物技术
目录
一、背景介绍
二、Monkey诞生
1. 出发点
2. 核心能力介绍
2.1 Monkey端侧自动化能力
2.2 Monkey平台化能力建设
2.3 Monkey自动化测试核心流程
三、Monkey创新过程
1. 智能模拟用户行为
2. Monkey结合B端组件测试
2.1 结合大仓组件能解决什么问题
2.2 结合大仓组件实践
2.2.1 ProTable单品类组件行为分析&拆解实战
2.2.1.1 操作行为分析
2.2.1.2 拆解步骤
2.2.1.3 注意事项
2.2.2 ProForm单品类组件行为分析&拆解实战
2.2.2.1 操作行为分析
2.2.2.2 拆解步骤
2.2.2.3 ProForm准确提交率
2.3 表单项数据填充
2.3.1 表单项 - Input types 通用填充
2.3.2 表单项 - 精准填充
3. 实时验证前后端接口参数一致性
4. 自动化错误捕获
4.1 错误类型分类
4.2 常规错误捕获
5. 用例模型定制化配置
四、Monkey可行性探索情况
1. 数据分析
2. 有效错误率统计
五、总结 & 规划
一
背景介绍
单元测试测试颗粒度较小 大部分单侧逻辑局限于函数级别的验证,难以覆盖整体流程
改变研发流程具有挑战性:研发团队通常会专注于新功能的开发和问题修复,所以增加测试用例录制的环节可能会对时间和资源带来压力。 用例维护成本较高:在敏捷迭代中,页面UI频繁变动和核心链路不断更新迭代, 录制生成的测试用例可能在下一次迭代中变得不再适用或无法执行,意味着测试用例需要进行不断的更新和维护。
二
Monkey诞生
Monkey , 也有人叫做搞怪测试,一般指用毫无规律的指令或操作去测试被测系统,观察被测系统的稳定性。
出发点
测试流程的自动化,降低测试成本同时提高准确性和覆盖率。 线上问题前置化,及早现版本可能存在白屏、接口请求响应异常、JavaScript运行时报错等常见的通用问题,保障系统在线上环境的稳定性。
核心能力介绍
Monkey端侧自动化能力

Monkey平台化能力建设

Monkey自动化测试核心流程

准备阶段:在这个阶段,首先需要进行B端SSO系统的免登,以确保Monkey能够正常登录系统。同时还需要获取天网菜单数据源,以便后续的操作可以正确地找到对应的页面和元素。 执行阶段:在这个阶段,使用Puppeteer提供的客户端浏览器环境,搭载随机测试脚本,模拟用户的行为操作(简称Monkey Runner)。通过这种方式,Monkey执行ProTable、ProForm测试模型用例,包括点击、输入、选择等,以覆盖不同的测试场景。 数据劫持:在执行阶段下的操作行为中,Puppeteer会捕获异常情况。这些异常可能包括页面加载失败、元素找不到等问题。通过捕获这些异常,可以及时发现并处理潜在的问题,以提高系统稳定性。 数据清洗:在这个阶段,基于Node服务实现数据上报和清洗。Monkey会将执行阶段下的操作行为数据上报给后台服务,后台服务可以对这些数据进行分析和处理,以生成测试报告、统计指标等。同时,也可以对数据进行清洗,以去除无效或冗余的信息,保持数据的准确性和可用性。
三
Monkey创新过程
智能模拟用户行为

高覆盖率:通过随机输入的方式,能够触发系统中各种不同操作。 发现意料之外的异常:由于随机性,Monkey 能够发现一些预料之外的异常情况,帮助提前发现潜在问题。
准确性和可重复性受限:由于随机生成输入的特性,Monkey 无法保证测试的准确性和可重复性,可能导致某些特定场景下的行为无法被模拟。 无法模拟特定场景下的用户行为:由于随机性导致无法模拟特定用户行为和上下文环境,不利于测试特定场景下的交互和功能。
Monkey结合B端组件测试
结合大仓组件能解决什么问题
结合大仓组件实践
01
ProTable单品类组件行为分析&拆解实战

操作行为分析
表格数据加载:用户打开包含ProTable组件页面时,首先会加载数据并显示在表格,数据源通过接口请求获取。 条件筛选和重置:对ProTable进行条件筛选以便查看数据,也可以重置筛选条件以恢复初始状态。 表格分页查询:使用分页器进行翻页等操作,以便展示更多的数据内容。
拆解步骤
测试用例:通过DOM Class 或者ID查询判定是否存在元素。
测试用例: 验证表格的搜索功能是否正确响应用户输入,并能正确筛选和显示符合条件的数据。 测试用例:模拟点击重置按钮,并确保表单数据被成功重置为默认值。
测试用例:点击页面切换按钮或输入页码,验证表格切换 调用接口有无异常。
测试用例:请求到数据,列表元素正常渲染。
注意事项
安全区域操作约束
在测试环境中,一些删除或更改操作可能会导致测试数据的不一致性或损坏,因此需要对测试环境中的点击行为进行约束,确保在安全区域内进行操作。优化导航栏点击
许多B端系统中,导航栏是一个常见的元素。为了更加精确地进行测试并提高效率,我们需要规避导航栏的点击或者A链接点击跳转,专注于当前页面的操作。
// 检查一个元素是否在另外一个元素中 原理类似于JQ $("#container").has(".selector"); const isSafeArea = (parentElement, childElement) => { const childClassNames = Array.from(childElement.classList); return childClassNames.every(className => parentElement.querySelector(`.${className}`));};const layoutContentElement = document.querySelector('.layout-content');const isisSafeAreaResult = isSafeArea(layoutContentElement,element)element.matches('a')
02
ProForm单品类组件行为分析&拆解实战
操作行为分析
数据加载或关闭:通过点击入口按钮显示弹窗,弹窗加载表单项:当用户完成操作后点击关闭按钮,弹窗关闭。 表单操作:在弹窗表单项中可以进行数据输入、选择选项、上传文件等操作。 数据校验:填写完表单数据后,ProForm组件会对表单数据进行校验,确保输入数据符合规定的格式要求。 数据提交:填写完表单数据后,通过点击提交按钮将数据提交到后端接口进行保存或更新。
拆解步骤
测试用例:通过DOM Class 或者ID查询 判定是否存在元素。
测试用例:表单项渐入数据 测试用例:验证表格的搜索功能是否正确响应用户输入,并能正确筛选和显示符合条件的数据。 测试用例:模拟点击重置按钮,并确保表单数据被成功重置为默认值。
测试用例:验证输入字段是否满足预期的格式,如邮箱地址格式、密码强度等。 测试用例:验证表单的必填字段是否被正确地标记,并且不能提交空值。
测试用例:模拟点击提交按钮拦截接口是有异常。
测试用例:模拟点击重置按钮,并确保表单数据被成功关闭。
ProForm准确提交率
前端准确提交率:确保表单项数据填充完整且点击提交按钮能触发提交接口(填写的数据能够通过前端校验) 业务准确提交率:前端准确提交基础上,要求提交接口返回的HTTP状态码为200且bsCode为200(填写的数据能够通过服务端校验)

为每个巡检的页面 URL 分配唯一的 UID,并记录 UID 与 Page URL 的映射关系。 当页面弹出新增弹窗时,填充完数据并点击提交,记录事件类型为 event_type = 'CLICK',同时记录时间戳和 UID。 劫持接口数据,并记录事件类型为 event_type = 'RESPONSE'。 对 event_type = 'RESPONSE' 的时间戳进行分组统计,确保大于 event_type = 'CLICK' 的时间戳。

表单项数据填充

01
表单项 - Input types 通用填充
B端系统未接入类型检测工具, 接口请求参数类型约束不严格。Monkey 会根据 Input Types 类型随机生成字符串,填充表单项以触发接口调用,发现接口参数类型错误。
穷举表单项的填充方式(MDN输入元素):文本类型(input type="text")、数据类型 (input type="number")、邮箱类型 (input type="email")、日期类型(input type="date")、单选框 类型(input type="radio")、复选框类型(input type="checkbox")


// input type 集合const defaultMapElements = { textarea: fillTextAreaElement, 'input[type="text"]': fillTextElement, 'input[type="password"]': fillTextElement, 'input[type="number"]': fillNumberElement, select: fillSelect, 'input[type="radio"]': fillRadio, 'input[type="checkbox"]': fillCheckbox, 'input[type="email"]': fillEmail, 'input:not([type])': fillTextElement, }; // 填充逻辑 const fillTextElement = async (element, character) => { const selectedCharacters = Array.from({ length: 5 }, () =>randomizer.getCharacter[Math.floor(Math.random() * randomizer.getCharacter.length)]).join(''); const newValue = element.value + (character ? character : selectedCharacters); if (element) { triggerSimulatedOnChange(element, newValue, window.HTMLInputElement.prototype); return newValue; } }; // Hacky function to trigger react, angular & vue.js onChange on input const triggerSimulatedOnChange = (element, newValue, prototype) => { const lastValue = element.value; element.value = newValue; const nativeInputValueSetter = Object.getOwnPropertyDescriptor(prototype, 'value').set; nativeInputValueSetter.call(element, newValue); const event = new Event('input', { bubbles: true }) as CustomEvent; // React 15 event.simulated = true; // React >= 16 let tracker = element._valueTracker; if (tracker) { tracker.setValue(lastValue); } element.dispatchEvent(event); };案例:后台页面Barcode条件筛选系统异常。
归因:前端未限制Barcode只能输入Number类型;服务端用Long类型字段接收BarCode字段,随机输入了String类型的值时,系统出现异常。
场景 - 服务端接口参数未校验



场景 - 服务端接口参数已校验



02
表单项 - 精准填充

实时验证前后端接口参数一致性
案例:后台页面筛选条件返回结果错误。
归因:接口字段改动,前端接口请求参数字段名错误。

自动化错误捕获
错误类型分类

常规错误捕获






用例模型定制化配置

文档和示例:提供详细的文档和示例,帮助用户理解如何配置Monkey的用例模型,以及如何利用上述的配置文件、可视化界面和扩展机制来定制Monkey的行为。这样可以让用户更容易上手,并且了解如何利用Monkey的定制化设置来满足不同的测试需求。 可视化配置界面:为了提高易用性,可以开发一个可视化的配置界面,让用户可以通过图形化界面来配置Monkey的行为模式和参数,而不需要直接编辑配置文件。这样的界面可以提供简单的拖拽、下拉菜单等操作,让用户能够直观地配置Monkey的行为。 插件化扩展机制:为了未来开放给用户并支持更多定制化需求,设计一个插件化的扩展机制,让用户可以编写自定义的插件来扩展Monkey的行为模式。这样的扩展机制可以提供接口和文档,让用户能够编写自定义的行为模式、触发条件等,从而实现更灵活的定制化设置。
四
Monkey可行性探索情况
数据分析


有效错误率统计

五
总结 & 规划
优化现有组件的数据匹配准确率。 组件品类的扩充,扩大支持的组件品类,覆盖更广泛的测试场景。 定制化配置用例模型,旨在提高错误类型识别的准确性。 提高系统的运行效率,计划整合CI/CD流程。