最近学习了翟志军老师写的《Jenkins 2.X实践指南》书中的第5章:代码质量一节,发现两方面问题:
1, 书中的描述不够清晰;
2, 也许是版本的问题,有些操作发生变化。
现在把我的学习结果汇集成此文,并且详细介绍我在学习过程中遇到的坑,希望对大家有所帮助。
利用Jenkins pipeline配置测试工具一般来说包含以下几个步骤:
1, 准备被测代码;
2, 安装测试工具,进行相应配置;
3, 安装Jenkins对应插件,并且进行配置;
4, 修改pom.xml文件;
5, 建立jenkinsfile文件。
由于这里要用到最新版本的Sonaqube,必须支持JDK11。
1 设置环境变量
1.1 JDK
1.1.1配置JDK
在“全局工具配置中(Global Tool Configuration)”找到图1选项。
图1 Jenkins JDK配置前的界面
在初始化界面,有一个“Please enter your username/password”的超级链接,点击进去,如果你没有设置过Oracle账号,请设置一个,然后在这里输入注册好的用户名和密码。安装完毕如图2 所示。
图2 Jenkins JDK配置后的界面
1.2 MAVEN
1.2.1 配置MAVEN
在“全局工具配置中(Global Tool Configuration)”找到图3选项。
图3 Jenkins MAVEN配置后的界面
1.2.2 建立Jenkinsfile
在Jenkinsfile中作如下设置。
pipeline{ agent any tools{ maven 'mvn-3.6.3' } stages{ stage('Build'){ steps { bat "mvn -v" echo "Finsh installMaven" } } } }
注意,这里maven 'mvn-3.6.3'中的mvn-3.6.3必须与图3中设置得一致。
1.3 Python
1.3.1安装Jenkins PyenvPipeline插件
进入Jenkins插件中心,下载安装Pyenv Pipeline,如图4所示。
图4安装Jenkins Pyenv Pipeline插件
1.3.2 安装virtualenv
1. 下载虚拟环境
打开cmd,通过以下命令安装虚拟环境。
C:\Users\xiang>pip3 installvirtualenvwrapper-win
2. 配置环境变量WORKN_HOME,值为C:\Users\{username}\Envs。如图5所示。
图5 配置WORKN_HOME环境变量
3. 创建当前版本虚拟环境
C:\Users\xiang>mkvirtualenv bobbyvir
1.3.3 建立Jenkinsfile
pipeline{ agent any stages{ stage("Build"){ steps{ withPythonEnv("C:\\Users\\xiang\\AppData\\Local\\Programs\\Python\\Python38\\"){ bat "python--version" } echo "python is ok" } } } }
其中C:\\Users\\xiang\\AppData\\Local\\Programs\\Python\\Python38\\为python的安装路径。
2. 配置测试工具
2.1 PMD
PMD是一款采用BSD协议发布的Java程序代码检查工具。该工具可以做到检查Java代码中是否含有未使用的变量、是否含有空的抓取块、是否含有不必要的对象等。该软件功能强大,扫描效率高,是Java程序员debug的好帮手。
- 与其他分析工具不同的是,PMD通过静态分析获知代码错误。也就是说在不运行Java程序的情况下,报告错误。
- PMD附带了许多可以直接使用的规则,利用这些规则可以找出Java源程序的许多问题。
- 此外,用户还可以自己定义规则。检查Java代码是否符合某些特定的编码规范。常见的类型如下:
①潜在的bug:空的try/catch/finally/switch语句。
②未使用的代码:未使用的局部变量、参数、私有方法等。
③可选的代码:String/StringBuffer的滥用。
④复杂的表达式:不必须的if语句、可以使用while循环完成的for循环。
⑤重复的代码:拷贝/粘贴代码意味着拷贝/粘贴bugs。
⑥循环体创建新对象:尽量不要再for或while循环体内实例化一个新对象。
⑦资源关闭:Connect,Result,Statement等使用之后确保关闭掉。
此外,用户还可以自己定义规则,检查Java代码是否符合某些特定的编码规范。例如,你可以编写一个规则,要求PMD找出所有创建Thread和Socket对象的操作。
2.1.1建立Project。
这个Project为基于Java的TestNGProject。被测程序如下:
packagecom.jerry.mytest; publicclass Calculator { private static int result; public void add(int n) { result = result + n; } public void substract(int n) { result = result - n; } public void multiply(int n) { result= result * n; } public void divide(int n) { result = result / n; } publicvoid square(int n) { result = n * n; } public void squareRoot(int n) { for (; ;) ; } public void clear() { result = 0; } public int getResult() { return result; } }
这个文件位于.\src\main\java\com\jerry\mytest\Calculator.java。测试程序为:
packagecom.jerry.mytest; importorg.testng.annotations.Test; importorg.testng.AssertJUnit; importorg.testng.annotations.BeforeMethod; publicclass CalculatorTest { private static Calculator calculator = newCalculator(); @Test public void testAdd() { calculator.add(2); calculator.add(3); AssertJUnit.assertEquals(5,calculator.getResult()); } @Test public void testSubstract() { calculator.add(5); calculator.substract(3); AssertJUnit.assertEquals(2, calculator.getResult()); } @Test public void testMultiply() { calculator.add(3); calculator.multiply(2); AssertJUnit.assertEquals(6,calculator.getResult()); } @Test public void testDivide() { calculator.add(9); calculator.divide(3); AssertJUnit.assertEquals(3,calculator.getResult()); } @BeforeMethod public void beforeMethod() { calculator.clear(); } }
下面没有特别说明都用这个Project。
2.1.2安装Jenkins的PMD插件
进入Jenkins插件中心,安装PMD插件,如图6所示。
图6 安装Jenkins PMD插件
2.1.3修改pom.xml文件
<dependency> <groupId>com.alibaba.p3c</groupId> <artifactId>p3c-pmd</artifactId> <version>1.3.5</version> <scope>test</scope> </dependency> … <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jxr-plugin</artifactId> <version>2.3</version> </plugin>
2.1.4建立Jenkinsfile
pipeline{ agent any tools{ maven 'mvn-3.6.3' } stages{ stage('pmd'){ steps { bat "mvn pmd:pmd" bat "mvn pmd:pmd" } } } post{ always{ pmd(canRunOnFailed:true,pattern:'**/target/pmd.xml') } } }
2.1.5构建
图7为构建完毕后的界面,没有发现违法规则的地方。
图7 PMD构建结果
2.2 JUnit
关于JUnit,在这里就不做过多介绍,大家应该比较熟悉。
2.2.1安装Jenkins JUnit插件
进入Jenkins插件中心,安装JUnit插件,如图8所示。
图8 安装Jenkins JUnit插件
2.2.2 修改pom.xml文件
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>2.4.2</version> <configuration> <skipTests>true</skipTests> </configuration> </plugin> … <dependency> <groupId>org.testng</groupId> <artifactId>testng</artifactId> <version>6.14.2</version> </dependency> …
2.2.3建立Jenkinsfile
stage('junit'){ steps { bat "mvn test" } } post{ always{ junit testResults: "**/target/surefire-reports/*.xml" } }
2.2.4 构建
图9为构建完毕后的界面,点击TestResult 超链可以查看详细地测试结果。
图9 JUnit构建结果
2.3 Jacoco
JaCoCo支持多种覆盖率的统计,包括:
- 行覆盖率:度量被测程序的每行代码是否被执行,判断标准行中是否至少有一个指令被执行;
- 类覆盖率:度量计算class类文件是否被执行;
- 分支覆盖率:度量if和switch语句的分支覆盖情况,计算一个方法里面的总分支数,确定执行和不执行的分支数量;
- 方法覆盖率:度量被测程序的方法执行情况,是否执行取决于方法中是否有至少一个指令被执行;
- 指令覆盖:计数单元是单个java二进制代码指令,指令覆盖率提供了代码是否被执行的信息,度量完全独立源码格式;
- 圈复杂度:在(线性)组合中,计算在一个方法里面所有可能路径的最小数目,缺失的复杂度同样表示测试案例没有完全覆盖到这个模块。
- 3.1安装Jenkins Jacoco插件
进入Jenkins插件中心,安装Jacoco插件,如图10所示。
图10 安装Jenkins Jacoco插件
2.3.2修改pom.xml文件
<build> <plugins> <plugin> <groupId>org.jacoco</groupId> <artifactId>jacoco-maven-plugin</artifactId> <version>0.8.2</version> <executions> <execution> <id>prepare-agent</id> <goals> <goal>prepare-agent</goal> </goals> </execution> <execution> <id>report</id> <phase>prepare-package</phase> <goals> <goal>report</goal> </goals> </execution> <execution> <id>post-unit-test</id> <phase>test</phase> <goals> <goal>report</goal> </goals> <configuration> <dataFile>target/jacoco.exec</dataFile> <outputDirctory>target.jacoco.exec</outputDirctory> </configuration> </execution> </executions> <configuration> <syatemPropertyVariable> <jacoco-agent.destfile>target/jacoco.exec/</jacoco-agent.destfile> </syatemPropertyVariable> </configuration> </plugin> </plugins> </build>
注意:jacoco-maven-plugin必须设置在<build>… </build>之间。
2.3.3立Jenkinsfile
… stage('jacoco'){ steps{ bat "mvn clean install" jacoco( execPattern:'target/**/*.exec ', //代码覆盖率统计文件位置 classPattern:'target/classes', //class文件位置 sourcePattern:'src/main.java', //源代码文件位置 exclusionPattern:'src/test*', //排除分析文件位置 skipCopyOfSrcFiles:false, //是否禁用每行每行覆盖率文件的原文件显示 changeBuildStatus:true, minimumInstructionCoverage:'30', maximumInstructionCoverage: '70', //字节码指令覆盖率 minimumLineCoverage:'30', maximumLineCoverage: '70', //行覆盖率 minimumComplexityCoverage:'30', maximumComplexityCoverage: '70', //圈复杂度覆盖率 minimumMethodCoverage:'30', maximumMethodCoverage: '70', //方法覆盖率 minimumClassCoverage:'30', maximumClassCoverage: '70', //类覆盖率 minimumBranchCoverage:'30', maximumBranchCoverage: '70', //分支覆盖率 buildOverBuild:true, //各个维度覆盖率变化量阈值 deltaInstructionCoverage:'80', deltaLineCoverage: '80', deltaMethodCoverage:'80', deltaClassCoverage: '80', deltaComplexityCoverage:'80', deltaBranchCoverage: '80' ) } } …
当代码的覆盖率不符合设置的阈值,构建结束将会显示错误。
2.3.4构建
为了描述方便,在这里jacoco()方法不带任何参数,也就不做任何合法性检查,仅仅在构建结束展示覆盖率结果。构建完成结果如图11所示。
图11 Jacoco构建结果
2.4 基于Taurus的性能测试
这个案例需要单独建立一个Jenkins Project。
基于Taurus的性能测试是基于Python的,使用之前请务必确认系统中已经安装了Python环境,并且按照第1.3节进行配置。
Taurus 能够支持现有 JMeter、Grinder、Gatling、Selenium测试引擎的能力,同时也能够支持直接解析原生脚本,如 JMeter JMX文件。其默认执行引擎是 JMeter,因此,如果已经使用 JMeter创建了 JMX 文件,那么使用 Taurus 可以很容易地运行,只需使用 bzt 命令以及 JMX 路径即可。
2.4.1安装Jenkins Performance插件
进入Jenkins插件中心,安装Jacoco插件,如图12所示。
图12 安装Jenkins Performance插件
2.4.2安装Taurus
在安装Performance插件的时候会自行安装Taurus。打开CMD,运行如下代码。
>pip3 install bzt
2.4.3配置yml文件
blaze_exist_jmeter_config.yml execution: - scenario: simple scenarios: simple: script: ebusiness.jmx modules: jmeter: download-link:https://mirrors.tuna.tsinghua.edu.cn/apache//jmeter/binaries/apache-jmeter-{version}.zip
version:5.2.1
配置yml文件千万需要注意:
- 1. 冒号:后面必须有空格;
- 2. 文件里面不允许出现Tab,要以空格代替。
在这里:
- ebusiness.jmx为需要进行性能测试的由JMeter生成的文件
- 采用清华镜像网站mirrors.tuna.tsinghua.edu.cn,提高执行速度。
- 建立Jenkinsfile
pipeline{ agent any stages{ stage('performance test'){ steps{ bzt params:'blaze_exist_jmeter_config.yml' } } } }
配置完毕,可以手工运行如下命令进行测试。
C:\Users\xiang\.jenkins\workspace\JMeter>btzblaze_exist_jmeter_config.yml
2.4.5构建
图13为构建完毕后的界面,点击PerformanceReport超链可以查看详细地测试结果。
图13 JMeter构建结果
2.5 SonarQube
SonarQube基于本地服务和mvn命令进行的代码分析,并将分析结果推送到sonar服务器中。
SonarQube采用wrapper技术。在实际开发过程中很多模块需要独立运行,他们并不会以web形式发布,传统的做法是将其压缩为jar包独立运行,这种形式简单易行也比较利于维护,但是一旦服务器重启或出现异常时,程序往往无法自行修复或重启。解决服务器重启的传统做法是编写一段shell脚本随服务器启动而运行,但是这样做只是治标,那么我们想寻求一种“治本”的方式该怎么办呢?
Java Service Wrapper就轻松而简单的为我们解决了这些问题。"Java ServiceWrapper"顾名思义,将我们的Java程序包装成系统服务,这样就可以随着系统的运行而自动运行,当然JavaService Wrapper(下面简称Wrapper)的功能绝不仅于此。
2.5.1 下载安装配置SonarQube
1. 下载安装
到https://www.sonarqube.org/downloads/下载最新版本的SonarQube,本文使用的是 8.1.0.31237。下载完毕进行安装,安装完毕的目录结构如图14所示。
图14 SonarQube的目录结构
其中:
- bin:执行文件路径,其中:
- linux-x86-64:为Linux的执行路径;
- macosx-universal-64:为MAC的执行路径;
- windows-x86-64:为64 Windows的执行路径。
- conf:配置文件路径,其中:
- sonar.properties:配置sonar;
wrapper.conf:配置wrapper。
- extensions:插件库路径,一般插件存储在. \extensions\plugins\路径下。
- log:日志文件,其中:
- web.log:为SonarQube WEB的日志文件;
- sonar.log:为Sonar服务器的日志文件。
- 配置数据库
SonarQube已经不支持MySQL,现在支持Oracle 11g/12c/18c/19c、PostgreSQL 9.3 or greater和Microsoft SQLServer 2014/2016/2017and SQL Azure。这里我们以MicrosoftSQLServer 2014为例。
严格按照https://www.cnblogs.com/advLuo/p/11455942.html进行配置。特别注意图15和图16。
图15 数据库的排序方式
图16 打开1443端口
注意数据库必须用户SQL Server登录,如何设置,请参看https://jingyan.baidu.com/article/380abd0aa8f2311d90192cd0.html。