找回密码
 会员注册
查看: 20|回复: 0

社区项目迁移Diff自动化测试实践

[复制链接]

1

主题

0

回帖

4

积分

新手上路

积分
4
发表于 2024-10-9 01:47:47 | 显示全部楼层 |阅读模式
得物社区项目中包括内容搜索、穿搭精选、无结果推荐、搜索debug等功能。所有功能都在一个单体应用,各种本地缓存、配置、代码交织不利于维护;当某些功能有问题之后也会影响其他接口,不利于项目稳定性。本次需求RD打算将各类功能拆分到不同项目中。我在社区搜索迁移项目中首次落地了 Diff 自动化测试,从测试到上线的过程中,累计发现很多处bug,发现了很多潜在的、不易发现的问题;最终该项目上线后流量从5%提升到100%,仅用一周完成全量的切换,且过程中指标无异常。什么是Diff测试Diff测试,从字面意思上理解,就是对比测试。深入到项目中理解的话,比如某一个工程比较陈旧,代码过于冗余和复杂,维护成本较高,为了解决这些问题,会进行项目重构、框架升级、代码解耦等等。这样的项目有个特点:纯粹的代码优化、影响范围甚广、业务上有强烈需求要保证与之前的一致性。为了验证新的代码和老的代码达到的功能和效果是一致的,采用的结果比对的方式,这样的过程我们称之为Diff测试。新老项目迁移测试痛点老项目的业务逻辑复杂,场景较多,梳理困难;返回的结果数据字段也众多,甚至冗余,但属于对外协议的一部分的内容,又必须要逐个去校验,导致效率低下。我们接下来看看传统的Diff解决方案是怎么做的,对比传统的思路,再看我是怎么做的。传统的Diff解决方案因为业务差异性,传统解决方案并不能在我们公司很好地落地,主要有以下两点原因:公司当前RPC框架不支持泳道机制,需要额外搭建一套环境;而搜索的opensearch等组件外购于阿里云,额外部署的这部分成本会相对较高;还有环境相关问题,经团队内部讨论,也找了开发RD始终无法绕过,于是只能利用开发的AB机制,使用两组用户画像一致的uid,请求同一套环境,命中不同的AB新老框架,进行结果比对。新的Diff解决方案经过内部讨论以及测试,我们决定用新的Diff解决方案,如下图所示:当新的Diff方案能适应业务逻辑的时候,我们还要考虑一些其他的问题,如下:1.业务逻辑复杂场景多--如何尽可能的命中到场景?>>流量日志解析,根据场景筛选分布a.获取线上热词100条,遍历验证Diff结果b.少结果、无结果推荐c.验证热搜置顶位、运营位、人为强干预d.接口支持的常规筛选参数e.App版本兼容性——478、479f.不同平台兼容性——ios、android、h5g.翻页h.线上实验组遍历>>随机流量a.线上随机抽取真实用户画像2.字段对比的实现思路多种对比模式:仅字段数据结构,仅判断不为空统一格式转换:白名单额外信息字段补进对比结果自动入库3.如何做到迅速分析归因?当有bug导致不一致时,比如某个字段丢失,会大量的失败,如何确定还有无其他的bug?黑名单过滤机制总结与反思诚然本次Diff发挥了很好的效果,但是Diff测试并不是完美无缺的,项目结束,和项目成员内部对齐了下,至少还有以下两个可以持续改进的点:1.覆盖率无法完全保证,仅能从流量场景入口尽可能覆盖,但是数据场景无法构造是天然的缺陷;2.发现问题的时机只有新老对比这一次,错过会一直存在,所以对问题归因务必要仔细;当然这两个问题虽然完全解决比较困难,也有尽量减少影响的方案,我对Diff测试保持信心!补充阅读-自动化工程代码实现代码逻辑流程图表结构设计项目工程相关类IDiffFactoryService/** * @author Chris * @version 1.0 * @date 2021/10/8 11:32 上午 */public interface IDiffFactoryService { /** * 根据env环境动态获取域名 * @param path * @return */ String getPath(String path); /** * 发送接口请求 * @param path * @param param * @param method * @return */ JSONObject getResponseHttp(String path, Object param, String method); /** * 过滤部分字段,返回response * @param jsonObject * @param filterList * @return */ JSONObject getFilterRespone(JSONObject jsonObject, List filterList); /** * 对比结果 * @param oldJSONObject * @param newJSONObject * @param keyList (keyList为空,对比过滤后的字段,keyList不为空,则仅对比指定key的返回结果) * @return */ AlgDiffResult getDiffResult(JSONObject oldJSONObject, JSONObject newJSONObject, List keyList);}IDiffService/** * @author Chris * @version 1.0 * @date 2021/10/8 11:47 上午 */public interface IDiffService { /** * 整合并实现数据的请求及结果对比 * * @param diffParamRequest * @return */ AlgDiffResult diffCompare(DiffParamRequest diffParamRequest); /** * 造数工具——批量生成用例 * * @param bodyRequest * @return */ List getOrAddCases(BodyRequest bodyRequest); /** * 执行单条用例对比 * @param caseId */ void diffCompareCase(int caseId); /** * 遍历执行一个接口下的所有用例 * @param paramId */ void diffCompareParam(int paramId); /** * 遍历执行一个项目下的所有用例 * @param projectId */ void diffCompareProject(int projectId);}CommunityDiffTest @DataProvider(name = "query") public Iterator dataQuery() { List listObj = ListUtil.toList(); String content = iAlgTestDataService.getById(1).getContent(); String[] strings = StrUtil.split(content, ","); for (String str : strings) { listObj.add(str.trim()); } return listObj.iterator(); } @Test(dataProvider = "query", testName = "热词") public void test(String data) { ContentSearchParam contentSearchParam = new ContentSearchParam(); contentSearchParam.setQuery(data); diffTest(contentSearchParam, ListUtil.toList("productMenu", "tags")); }*文:胡朝阳得物技术? 关注我们,做最潮技术人!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 会员注册

本版积分规则

QQ|手机版|心飞设计-版权所有:微度网络信息技术服务中心 ( 鲁ICP备17032091号-12 )|网站地图

GMT+8, 2025-1-8 11:50 , Processed in 0.504126 second(s), 25 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表