测试驱动开发:基于Jenkins+GoTest+HTML的持续化集成

目录

前言        

一、项目框架

1.项目迭代

2.项目时序图

3.项目测试执行

二、项目具体实现

1.创建流水线

2.拉取代码

3.执行测试代码

4.生成测试报告

5.报告内容解读

6.数据统计

7.邮件通知

8.企业微信通知

三、项目遇到的问题

1.go test -args 

2.go test生成html格式的报告

3.数据统计问题

4.相对路径问题

5.错误排查问题


前言        

       目前我们的项目体系流程不够完善,我们针对这一现象引入了“测试驱动开发”观念,在开发测试部署阶段可以节省一部分工作量,对于比较复杂的场景,也可以编写一些测试工具。我们都知道如果仅靠传统的手工测试(偏功能)会存在很多的漏洞,为了提高迭代效率,引入自动化测试、CI/CD,在项目测试阶段、预上线、上线等各个阶段都能快速通过上述手段发现问题,保障产品质量。

     


一、项目框架

        在日常测试过程中,需要验证测试环境&线上环境API接口,为了更方便,研究了通过Jenkins构建自动化项目并生成HTML报告。接下来会详细介绍项目构建步骤和遇到的问题。

1.项目迭代

2.项目时序图

3.项目测试执行


二、项目具体实现

1.创建流水线

(1)新建任务

(2)选择流水线或者复制现有流水线任务

(3)配置流水线

(4)pipeline脚本的基本框架

#!groovypipeline {agent anyenvironment {GO_BINARY = "go"TEST_REPORT_PATH = "test-report.xml"}stages {stage('checkout') {steps {sh"""echo "steps one""""}}stage('unit-test') {steps {echo "step two"}}stage('api-test') {steps {sh """ehco "step three""""}}}post {always {echo "clean over..."echo "send email"}success {echo 'Build && Test Succeeded.'}failure {echo 'Build && Test Failured.'}}}

对应在jenkins上的阶段视图:

2.拉取代码

repoURL = "git拉取代码地址"rootPath = "/var/jenkins_work/workspace/pid-openapi-test-report"repoPath = "${rootPath}/$BUILD_ID"...stages {stage('checkout') {steps {sh"""export PATH="${arcPath}:${goRoot}:${kubectlRoot}:${makeRoot}:$PATH"git clone --depth 1 ${repoURL} ${repoPath}"""}}...}

3.执行测试代码

利用go test命令执行代码。执行go test会进行全代码编译的,会拉取所有的依赖,所以需要提前配置go环境变量。

go test运行指定模块、指定优先级的测试用例,eg:

go test -v ./test/storage/... '-run=^Test+/TestP0' -json

./test/storage/ storage在openapi-go项目中的代码目录

'-run=^Test+/TestP0' ^Test指定Test打头的suite,/TestP0指定该suite下的用例。这样可以将模块storage、用例名称TestP0参数化为MODULE_NAME、PRIORITY,并在jenkins上的参数化构建中进行赋值。

配置完成后go test可以写成这样了:

go test -v ./test/$MODULE_NAME/...   -run="^Test"+"/Test"+$PRIORITY

4.生成测试报告

安装go-test-report

go get github.com/vakenbolt/go-test-report/

执行生成html格式测试报告的命令,会在当前目录生成一个test_report.html

go test -v ./test/$MODULE_NAME/...   -run="^Test"+"/Test"+$PRIORITY   -json | go-test-report

jenkins发布报告的pipeline script:

stage('Report') {           steps {echo "report"publishHTML (target: [allowMissing: false,alwaysLinkToLastBuild: false,keepAll: true,reportDir: '$BUILD_ID/test-output',reportFiles: 'test_report.html',reportName: "HTML Report"])}}

然后就可以在jenkins查看该报告了

5.报告内容解读

失败的用例是红色,通过的用例是绿色。失败日志需要关注assert部分的日志,包括报错行数、期望值与实际值的比较结果。

6.数据统计

在测试代码执行结果及报告都有了之后就可以统计自已需要的数据,然后放在邮件内容里进行发送。

先分析下html源文件的内容,找到自已想要的数据。

groovy自带解析html格式的库,但是不太好用。这里采用awk解析数据。

注:substr(s,p,n) 返回字符串s从p开始长度为n的部分

def genReportBody() {// 生成测试报告内容def testReport = readFile("$BUILD_ID/test-output/test_report.html")// 获取执行时间sh(script: 'pwd')def duration = sh(script: 'grep "Duration:" '+"$BUILD_ID/test-output/test_report.html"+' | awk \'{print substr($6,9,length($6)-17)}\'', returnStdout: true).trim()echo durationdef runtime = duration.split("\\.")[0].trim()echo runtime// 获取总数量def total = sh(script: 'grep "Total:" '+"$BUILD_ID/test-output/test_report.html"+' | awk \'{print substr($5,9,length($5)-26)}\'', returnStdout: true).trim()// 获取通过率def passedCount = sh(script: 'grep "Passed:" '+"$BUILD_ID/test-output/test_report.html"+' | awk \'{print substr($5,9,length($5)-17)}\'', returnStdout: true).trim()def skippedCount = sh(script: 'grep "Skipped:" '+"$BUILD_ID/test-output/test_report.html"+' | awk \'{print substr($5,9,length($5)-17)}\'', returnStdout: true).trim()def failedCount = sh(script: 'grep "Failed:" '+"$BUILD_ID/test-output/test_report.html"+' | awk \'{print substr($5,9,length($5)-17)}\'', returnStdout: true).trim()def passedRate = String.format("%.2f", passedCount.toInteger()/(total.toInteger()-skippedCount.toInteger()) * 100)

7.邮件通知

组装邮件中的内容

 // 生成测试报告def reportContent = """<h2>OpenAPI Test Report (${MODULE_NAME})</h2><p>Environment: ${ENV}</p><p>Test Time: ${runtime}s</p><h3>Test Cases:</h3><ul><a href="https://jenkins地址/view/pid/job/${JOB_NAME}/$BUILD_ID/HTML_20Report/" target="_blank">https://jenkins地址/view/pid/job/${JOB_NAME}/$BUILD_ID/HTML_20Report/</a></ul><p>Pass Rate: ${passedRate}% </p><p>Test Range: ${PRIORITY}</p><h3>Failures: ${failedCount}</h3>"""发送邮件,在发送邮件前将无用的测试数据清除post {always {sh """mv ${repoPath}/test-output ~/temprm -rf ${repoPath}/*mv ~/temp/test-output ${repoPath}/"""echo "clean over..."emailext body:  genReportBody(),subject: 'Test Report',// to: 'env.RECIPIENTS',to: '${RECIPIENT_LIST}',mimeType: 'text/html'// from: '邮件发送地址'}success {echo 'Build && Test Succeeded.'}failure {echo 'Build && Test Failured.'}}

8.企业微信通知


三、项目遇到的问题

1.go test -args 

利用该命令自定义参数时发现-args后面所有东西都当成agrs的值,且阻断后面所有指令的执行。后来在stackoverflow看见一个人发了同样的问题,我想到去看下官方说明

In addition to the build flags, the flags handled by 'go test' itself are:-argsPass the remainder of the command line (everything after -args)to the test binary, uninterpreted and unchanged.Because this flag consumes the remainder of the command line,the package list (if present) must appear before this flag.

上面的everything after -args和执行实际效果是一样。这样通过命令行方式来切换环境的做法是行不通,于是采用多个配置文件的方式,全部存放在jenkins机器的~/conf目录。

切换方式

if [ $ENV = "test" ]thenecho 'cp test .env'cp /home/jenkins/conf/.env ${repoPath}/testcp /home/jenkins/conf/.env.storage ${repoPath}/test/storage/v1/.envelif [ $ENV = "dev" ]then#statementsecho 'cp dev .env'cp /home/jenkins/conf/.env.dev ${repoPath}/test/.envcp /home/jenkins/conf/.env.storage.dev ${repoPath}/test/storage/v1/.envelif [ $ENV = "prod" ]thenecho 'cp prod .env'cp /home/jenkins/conf/.env.prod ${repoPath}/test/.envcp /home/jenkins/conf/.env.storage.prod ${repoPath}/test/storage/v1/.envfi

2.go test生成html格式的报告

最开始也是打算接入allure报告,但是发现go test并不支持,所以采用了go-test-report。发布的第一版的go test report时并不是长这样的

而是像下面这样不带css样式的

解决方法:在jenkins-->系统管理-->脚本命令行,输入以下命令

System.setProperty("hudson.model.DirectoryBrowserSupport.CSP", "")

3.数据统计问题

网上有很多groovy统计xml格式的文件,没找到能很好解析html格式的工具,想到awk这个工具。

def passedCount = sh(script: 'grep "Passed:" '+"$BUILD_ID/test-output/test_report.html"+' | awk \'{print substr($5,9,length($5)-17)}\'', returnStdout: true).trim()

4.相对路径问题

我们用IDE编写用例时直接就可以执行了,这种情况下go会把该用例所在的目录当成pwd目录;而流水线中go test是在项目根目录下执行的,这时go是把项目根目录当成pwd目录的。这样用例中使相对路径eg:.env、../.env等都会执行失败。

解决方法:利用runtime获取当前执行路径,然后代码中生成项目根目录,以该路径为基点再去拼接文件的路径,尽量不要使相对路径。

5.错误排查问题

后面发现现有的脚本case编写如果有一个报错,全部都是红色,找到报错点不是很方便,修改脚本case为:

func (s *JobBatchGetSuite) TestP0_Normal() {s.Run("TestSuccessJobBatchGet", func() {s.TestSuccessJobBatchGet()})
}func (s *JobBatchGetSuite) TestP1_Normal() {s.Run("TestJobBatchGetJobIdsTooMuch", func() {s.TestJobBatchGetJobIdsTooMuch()})
}

在jenkins上执行后,报告展示更为直观。

今天的分享就到此结束喽~

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

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

相关文章

ASO优化:巧用字符串

应用商店优化&#xff08;ASO&#xff09;与网站的搜索引擎优化 (SEO) 非常相似。 同样&#xff0c;应用程序商店通过关键字、评论、下载和升级数量以及其他排名因素来查找最相关的应用程序。 ASO 和 SEO 都致力于为产品带来更多流量&#xff0c;并将其置于搜索结果的顶部。 …

django后台进行加密手机号字段,加密存储,解密显示

需求: 1 &#xff1a;员工在填写用户的手机号时&#xff0c;直接填写&#xff0c;在django后台中输入 2&#xff1a;当员工在后台确认要存储到数据库时&#xff0c;后台将会把手机号进行加密存储&#xff0c;当数据库被黑之后&#xff0c;手机号字段为加密字符 3&#xff1a;员…

文心一言使用分享

ChatGPT 和文心一言哪个更好用&#xff1f; 一个直接可以用&#xff0c;一个还需要借助一些工具&#xff0c;还有可能账号会消失…… 没有可比性。 通用大模型用于特定功能的时候需要一些引导技巧。 import math import time def calculate_coordinate(c, d, e, f, g, h,…

Jenkins的环境部署,(打包、发布、部署、自动化测试)

一、Tomcat环境安装 1.安装JDK&#xff08;Java环境&#xff09; JDK下载地址&#xff1a;Java Downloads | Oracle 安装好后在系统环境变量里配置环境变量&#xff1a; ①添加JAVA_HOME 变量名&#xff1a;JAVA_HOME变量值&#xff1a;C:\Program Files\Java\jdk1.8.0_18…

Docker安全基线检查需要修复的一些问题

一、可能出现的漏洞 限制容器之间的网络流量 限制容器的内存使用量 为Docker启用内容信任 将容器的根文件系统挂载为只读 审核Docker文件和目录 默认情况下&#xff0c;同一主机上的容器之间允许所有网络通信。 如果不需要&#xff0c;请限制所有容器间的通信。 将需要相互通…

精品基于Uniapp+springboot农产品安全领域的信息采集系统App

《[含文档PPT源码等]精品基于Uniappspringboot农产品安全领域的信息采集系统App》该项目含有源码、文档、PPT、配套开发软件、软件安装教程、项目发布教程、包运行成功&#xff01; 软件开发环境及开发工具&#xff1a; 开发语言&#xff1a;Java 后台框架&#xff1a;sprin…

openEuler 下部署Zabbix报表系统zbxtable

1.zbxtable简单介绍 官网地址:使用文档 | ZbxTable ZbxTable 是使用 Go 语言开发的一个开源的 Zabbix 报表系统 目前已经推出 ZbxTable 2.1 版本 主要功能如下&#xff1a; 按照主机类型&#xff0c;展示或导出主机资源 资产管理&#xff0c;资源状态总览 多用户、角色、…

三、MySQL实例初始化、设置、服务启动关闭、环境变量配置、客户端登入(一篇足以从白走到黑)

目录 1、选择安装的电脑类型、设置端口号 2、选择mysql账号密码加密规则 3、设置root账户密码 4、设置mysql服务名和服务启动策略 5、执行设置&#xff08;初始化mysql实例&#xff09; 6、完成设置 7、MySQL数据库服务的启动和停止 方式一&#xff1a;图形化方式 方式…

Python 一行命令部署http、ftp服务

Python 一行命令部署http服务 文章目录 Python 一行命令部署http服务具体操作命令如下浏览器返回下载Python 一行命令部署FTP服务 具体操作命令如下 这个比nginx相对来说更加简单&#xff0c;可以用于部署特殊场景时如银行等部署时&#xff0c;各种权限控制&#xff0c;内网之间…

课表排课小程序怎么制作?多少钱?

在当今的数字化时代&#xff0c;无论是购物、支付、点餐&#xff0c;还是工作、学习&#xff0c;都离不开各种各样的微信小程序。其中&#xff0c;课表排课小程序就是许多教育机构和学校必不可少的工具。那么课表排课小程序怎么制作呢&#xff1f;又需要多少钱呢&#xff1f; …

java代码实现CAS

&#x1f339;作者主页&#xff1a;青花锁 &#x1f339;简介&#xff1a;Java领域优质创作者&#x1f3c6;、Java微服务架构公号作者&#x1f604; &#x1f339;简历模板、学习资料、面试题库、技术互助 &#x1f339;文末获取联系方式 &#x1f4dd; 系列专栏目录 [Java项目…

适合进阶学习的 机器学习 开源项目(可快速下载)

目录 开源项目合集[>> 开源的机器学习平台&#xff1a;mlflow/mlflow](https://gitcode.com/mlflow/mlflow)[>> 机器学习路线图&#xff1a;mrdbourke/machine-learning-roadmap](https://gitcode.com/mrdbourke/machine-learning-roadmap)[>> 机器学习理论和…