分布式用例执行

前言

这两天趁着有时间,我疯狂的码字了~~

背景

我们公司是做人工智能平台的,什么是人工智能呢? 大数据 + 机器学习。大数据运行的基本就不快。机器学习算法运行起来也是慢的让人泪流满面。在我们的集群配置下,我使用一个 5M 的数据从数据引入到数据处理,特征工程,模型训练和评估报告等等一整套线下模型调研流程要 10 分钟左右。所以单线程执行测试用例是不靠谱的。而 UI 自动化在一台机器上只能是单线程执行。所以多台机器同时运行 case 的分布式处理方案呼之欲出。

原理

原理其实很简单。 我分步骤说一下

  1. 我们是用 jenkins 做 CI 工具的。所以通过 jenkins 的 slave 机制添加多台 slave 机器当做测试机。配置测试机在同一时间只能运行一个任务,也就是不能并发执行。
  2. 创建一个可以并发的 job 然后把步骤一中的测试机注册到这个 job 中,我们姑且叫这个 job 为 run job。run job 在触发构建的时候在所有的测试机中查询空闲的测试机,如果有空闲的就到这台机器上执行测试任务。如果没有空闲的机器就等待直到有机器空闲。
  3. 我们把测试用例分成不同的 group,然后创建一个分发任务的 job,我们姑且叫这个 job 为 dispatch job。dispatch job 中配置一段 shell 脚本,通过 jenkins API 的方式调用 run job 并把 group 作为参数传递过去。这样我们在 dispatch job 中调用了 N 次 run job 也就是在不同的机器上同时跑不同的 group。
  4. 接下来我们要解决测试报告的问题。我要创建一个归集所有测试结果的 job,我们姑且叫它为 results job。results job 会拉取所有 run job 的测试结果并保存到特定位置
  5. 然后我们创建一个 merge 测试结果并生成测试报告的 job,我们姑且叫它为 report job。

总结一下我们需要多台测试机器和 4 个 job。分别是 dispatch job,run job,results job 和 report job。 大概的样子如下:

配置 slave 测试机

这个比较简单,大家可以到网上找详细的教程。只需要记得创建的 node 要统一一个 label 比较好管理。如下:

dispatch job

这个 job 基本就是由 shell 脚本构成的,通过 shell 来调用 jenkins 的 API。如下:

#!/bin/sh#输出构建者的信息
echo $BUILD_USER_EMAIL $BUILD_USER > tigger_user_info#检查是否有任务还在跑
STATUS=`curl -v --silent "http://jenkins.4paradigm.com/job/prophet-test-run/api/json?tree=builds\[result\]" 2>&1 | grep -o "{\"result\":null}"`#测试任务URL
RUN_JOB_URL="http://jenkins.4paradigm.com/job/prophet-test-run/buildWithParameters?token=prophet"if [ "$STATUS" = "" ]; thencurl "$RUN_JOB_URL&env=$env&branch=$branch&group=atomTest.xml"curl "$RUN_JOB_URL&env=$env&branch=$branch&group=model_train.xml"curl "$RUN_JOB_URL&env=$env&branch=$branch&group=dataload.xml"curl "$RUN_JOB_URL&env=$env&branch=$branch&group=smoke.xml"printf "下发测试任务成功!\n"
elseprintf "测试服务器繁忙,下发测试任务失败!\n"exit -1
fi#任务下发成功后删除上次构建产生的结果
rm -rf  ../../prophet-send-report/workspace/allure-results/*

逻辑比较简单,首先检查当前还有没有 run job 在执行,如果有,那么执行失败。其实应该等待的执行结束的,只是暂时还没加这段逻辑。如果没有 run job 在执行。那么调用 run job 的 API 把测试任务分发下去。其中要把一些参数传递过去。例如运行环境,测试代码分支,测试用例的 group

run job

这个 job 比较常规,配置有点多我不详细的列举了。无非就是配置 git lab,拉取测试代码并 build 运行测试。其中 slave 测试机是注册在这个 job 里的。有一个需要注意的地方是 run job 运行结束后触发下一个 results job,需要传递一个比较重要的参数-- build number。因为下一个 job 需要知道 run job 的 build number 好去归集测试结果。如下:

对了还有一个特别重要的东西。为了要把测试结果从 slave 测试机上拉到 jenkins 上。我们需要剑走偏锋。配置如下:


其实这个时候我们并不希望在 run job 上就生成 html 的 report,我们指向的目录也不是 report 的目录。而是存放测试结果的 xml 文件的目录。jenkins 默认是不会从 slave 测试机上拉取这些文件的。为了让 jenkins 拉取这些文件,所以我们利用这个 html report 插件强行让 jenkins 把他们拉取上来。

results job

这也是一个有 shell 构成的 job。脚本如下:

#!/bin/shsleep 5s
# 通过run job传递的build number 将测试结果保存到特定目录下
folder="../../prophet-test-run/builds/$upstream_build/htmlreports/HTML_Report" 
if [ -d "$folder" ]; thencp -r "$folder" ../../prophet-send-report/workspace/allure-results/$upstream_build
fi#获取测试执行Job里是否有未完成的任务
STATUS=`curl -v --silent "http://jenkins.4paradigm.com/job/prophet-test-run/api/json?tree=builds\[result\]" 2>&1 | grep -o "{\"result\":null}"`if [ "$STATUS" = "" ]; then#获取构建人信息user_email=`awk '{print $1}' ../../prophet-task-dispatch/workspace/tigger_user_info`user_name=`awk '{print $2}' ../../prophet-task-dispatch/workspace/tigger_user_info`#邮件任务URLEMAIL_JOB_URL="http://jenkins.4paradigm.com/job/prophet-send-report/buildWithParameters?token=report"#触发发送报告任务curl "$EMAIL_JOB_URL&user_email=$user_email&user_name=$user_name"printf "下发邮件发送任务!\n"
elseprintf "还有测试任务正在执行!\n"
fi

逻辑也十分简单,根据 run job 传递 build number,copy 测试结果到特定的目录。 这里简单说明一下 jenkins 的目录结构。每个 job 都是存放在一个叫 jobs 的目录下,job 目录里面有 builds 和 workspace 两个文件夹。builds 目录分别存放每一个 build 的执行结果,results job 就是跑去 run job 的 builds 目录 copy 执行结果到 reports 的 workspace 目录下 (run job 传递过来的 build number 起作用了). workspace 目录就是 jenkins 上看到的工作控件了。我们 shell 就是在这个目录下运行的。 还有一个事,每个 run job 都会调用 results job 的。但是我们只希望最后一个 run job 结束后才让 results job 调用下游的 report job 来生成 report 并发送邮件。所以我们的 shell 脚本中才会有判断当前还有没有 run job 运行的逻辑。没有了才会调用 report job

report job

终于到了 report job。我们做了一堆配置,写了一堆脚本就是为了能成功合并测试结果并生成 html 的 report。这个 job 的任务非常简单,results job 已经把之前运行的所有测试的结果 copy 到了 report job 的 workspace 下。所以它要做的事情只有两件事,合并测试结果生成 report 以及发送邮件。 由于我用的 report 框架是 allure,所以直接用的 jenkins 上针对这个框架的插件。所以配置基本是很简单的。如下:


每一种 report 框架都会有 merge 测试结果的机制。大家根据自己的使用情况选择吧。

澄清

我澄清一下我使用的框架吧。 语言是 java,框架主要用的 testng,selenide,maven。 report 框架为 allure。所以才有上面一整套的配置。如果大家用的技术体系不一样,上面的分发任务和生成 report 的配置可能是不一样的。

关于 report 框架:allure

这个所谓的分布式执行处理的最大的难点其实就是测试结果的归集和 html report 的生成。我们起码有一半的工作都是为了达到这个目的。所以选取一个好的 report 框架是比较重要的。因为我是 java 系么。所以选择了 allure。allure 在 merge 测试结果方面挺方便的,同时我觉得 allure 是流程测试中尤其是 UI 自动化测试中最好的 report 框架。所以在这里还是小推销一下。它的效果图如下:

可以看到它不仅有强大的测试分类功能。还可以详细的记录你每一步的操作并展示在 report 中。显示截图的功能也很棒。另外还有不同维度统计功能。例如这个时间统计:


可以看到它展示了每台 slave 测试机上的 case 运行时间。可以让你调整用例的分组策略。不会让某一个 group 运行时间过长影响整体运行效率。下面是只列出失败的 case:


下面是统计仪表盘:

具体的使用攻略大家翻一翻我之前的帖子吧。我有一些详细说明。 也可以到 git hub 上直接看官方的 wiki。

总结

OK 今天爆发了,连写了 3 篇。 之前大概快一个月没写文章了。今天就当补上了吧。其实这个方案是用 jenkins 的机制临时糊出来分布式执行。记得之前有人分享过自己开发的分布式框架。我感觉成本还是太高了,需要开发比较长的一段时间。 虽然用 jenkins 糊出来的这个方案看上去有点不伦不类的,但是够用。搭建起来也快,按着这篇文章搞,估计一两天也就把坑踩完,投入使用了。

 更多内容欢迎来到我的知识星球:
 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/30478.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于IDEA的Maven(properties属性配置)

&#xff08;property &#xff1a;财产&#xff09;properties&#xff1a;它的复数。 同样也是基于上篇博客进行学习。&#xff08;具体的全部项目代码和结构可以去查看上篇...&#xff09; <properties><!--当前jdk版本 , 这一步可以完全省略--><maven.com…

2024青海三支一扶招1910人7月6日笔试

&#x1f4e2;2024年青海省三支一扶计划招募1910人公告已发布&#xff01; 小&#x1f004;️帮大家整理好了考试关键时间点&#xff1a; ★ 报名时间&#xff1a;6月20日至6月25日 ★ 报名网站&#xff1a;青海省人事考试信息网&#xff08;www.qhpta.com&#xff09; ★ 网上…

android studio构建项目报错Could not create an instance of type com.android.build.api.variant.impl.Applicat

Could not create an instance of type com.android.build.api.variant.impl.ApplicationVariantImpl 这个错误通常是由于Gradle插件版本不兼容导致的。你可能正在使用的Gradle插件版本与你的Android Studio版本不兼容。 要解决这个问题&#xff0c;你可以尝试以下解决方法&a…

音视频入门基础:H.264专题(3)——EBSP, RBSP和SODB

音视频入门基础&#xff1a;H.264专题系列文章&#xff1a; 音视频入门基础&#xff1a;H.264专题&#xff08;1&#xff09;——H.264官方文档下载 音视频入门基础&#xff1a;H.264专题&#xff08;2&#xff09;——使用FFmpeg命令生成H.264裸流文件 音视频入门基础&…

行为树行为树行为树

行为树由一个个节点组成 结构&#xff1a;树状结构运行流程&#xff1a;从根节点开始自顶向下往下遍历&#xff0c;每经过一个节点就执行节点对应的功能。 我们规定&#xff0c;每个节点都提供自己的excute函数&#xff0c;返还执行失败/成功结果。 然后根据不同节点的执行结…

国产数据库中读写分离实现机制

在数据库高可用架构下会存在1主多备的部署&#xff0c;备节点可以根据业务场景分发一部分流量以充分利用资源&#xff0c;并减轻主库的压力&#xff0c;因此在数据库的功能上需要读写分离来实现。 充分利用备节点的资源&#xff0c;提升业务的吞吐量&#xff1b;防止运维等非业…

《算法设计与分析》第五六章:回溯法与分支限界法

文章目录 回溯法分支限界法一、本章作业1.活动安排问题2.旅行商问题3.单源最短路径4.任务分配问题 二、算法积累1.回溯法求解01背包问题2.回溯法求解最大团问题3.回溯法求解n皇后问题4.回溯法求解地图着色5.回溯法求解哈密尔顿图6.回溯法求活动安排7.分支限界法求01背包问题8.分…

Flutter第十三弹 路由和导航

目标&#xff1a; 1.Flutter怎么创建路由&#xff1f; 2.怎么实现路由跳转&#xff1f;页面返回&#xff1f; 一、路由 1.1 什么是路由&#xff1f; 路由(Route)在移动开发中通常指页面&#xff08;Page&#xff09;&#xff0c;在Android中通常指一个Activity。所谓路由管…

小功率电机驱动方案中如何选择驱动IC

小功率电机驱动方案及驱动IC的选择 电机驱动作为工业4.0中工厂自动化整个闭环中的执行器环节&#xff0c;其性能好坏直接影响到整个闭环的性能。因此&#xff0c;工业4.0对电机驱动提出了更高的性能和功能要求&#xff0c;例如更快的响应速度、更高的带宽、更高精度的位置和速…

前端框架中的路由(Routing)和前端导航(Front-End Navigation)

聚沙成塔每天进步一点点 本文回顾 ⭐ 专栏简介前端框架中的路由&#xff08;Routing&#xff09;和前端导航&#xff08;Front-End Navigation&#xff09;1. 路由&#xff08;Routing&#xff09;1.1 定义1.2 路由的核心概念1.2.1 路由表&#xff08;Route Table&#xff09;1…

多模态大模型:基础架构

大模型技术论文不断&#xff0c;每个月总会新增上千篇。本专栏精选论文重点解读&#xff0c;主题还是围绕着行业实践和工程量产。若在某个环节出现卡点&#xff0c;可以回到大模型必备腔调或者LLM背后的基础模型重新阅读。而最新科技&#xff08;Mamba,xLSTM,KAN&#xff09;则…

gitee添加别人的仓库后,在该仓库里添加文件夹/文件

一、在指定分支里添加文件夹&#xff08;如果库主没有创建分支&#xff0c;自己还要先创建分支&#xff09; eg:以在一个项目里添加视图文件为例&#xff0c;用Echarts分支在usr/views目录下添加Echarts文件夹&#xff0c;usr/views/Echarts目录下添加index.vue 1.切换为本地仓…

Linux系统安装Ruby语言

Ruby是一种面向对象的脚本语言&#xff0c;由日本的计算机科学家松本行弘设计并开发&#xff0c;Ruby的设计哲学强调程序员的幸福感&#xff0c;致力于简化编程的复杂性&#xff0c;并提供一种既强大又易于使用的工具。其语法简洁优雅&#xff0c;易于阅读和书写&#xff0c;使…

重学java 66.IO流 转换流

且敬我疯狂&#xff0c;生命中不败的篇章 —— 24.6.11 一、字符编码 计算机中储存的信息都是用二进制数表示的&#xff0c;而我们在屏幕上看到的数字、英文、标点符号、汉字等字符是二进制数转换之后的结果。[按照某种规则&#xff0c;将字符存储到计算机中&#xff0c;称为编…

打造一个属于你的桌面天气 超级有个性的天气桌面

打造一个属于你的桌面天气 超级有个性的天气桌面。大家好&#xff0c;今天我们带来一个非常有趣的桌面天气工具&#xff0c;喜欢桌面diy的你&#xff0c;快点用上它吧&#xff01; 桌面上的美化&#xff0c;是许多爱美用户的心血和热爱。每个地方的美化&#xff0c;都是自己亲…

机器学习课程复习——隐马尔可夫

不考计算题 Q:概率图有几种结构? 条件独立性的公式? 顺序结构发散结构汇总结构Q:隐马尔可夫模型理解? 概念 集合:状态集合、观测集合 序列:状态序列、观测序列

linux环境编程基础学习

Shell编程&#xff1a; 相对的chmod -x xx.sh可以移除权限 想获取变量的值要掏点dollar&#xff08;&#xff04;&#xff09; 多位的话要加个花括号 运算&#xff1a;expr 运算时左右两边必须要加空格 *号多个含义必须加转义符 双引号可以加反单&#xff0c;但是发过来就不行 …

【android】安卓入门学习

文档介绍&#xff1a;http://8.136.122.222/book/primary/kotlin/kotlin-intro.html 文档补充说明&#xff1a;https://blog.csdn.net/qq_42059717/category_12047508.html 一、搭建环境及工具安装 见文档 二、工具界面及项目文件介绍 ├── app //工程主模块名称 │ …

【Linux安装Conda环境的详细教程】

&#x1f308;个人主页: 程序员不想敲代码啊 &#x1f3c6;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f44d;点赞⭐评论⭐收藏 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共…

PTP简介及Linux phy ptp驱动实现

1、PTP简介 PTP(precision time protocol)精确时间协议&#xff0c;是一种时间同步的协议&#xff0c;对应 IEEE 1588 标准&#xff0c;是基于网络数据包的一种时间同步协议&#xff0c;1588v2的同步精度可以达到ns级&#xff0c;但1588协议对硬件有依赖。 2、PTP原理 时间同…