接口自动化环境搭建(jmeter+ant+jenkins)

2023-09-22 18:07 胡钇臣 787

一、安装包准备

1.Jmeter

下载地址:http://jmeter.apache.org/download_jmeter.cgi

注:Windows和Linux都可以下载zip的包。建议下载5.1版本

2.Ant

下载地址:https://ant.apache.org/bindownload.cgi

注:Windows下载ZIP的包,Linux下载tar.gz的包,装1.9版本或1.10版本的都行。

3.Jenkins

下载地址:https://jenkins.io/download/

注:建议选择最新版。

4.jdk1.8

注:必须是1.8版本。

5.Xshell6或其他工具

二、安装所需的工具

(一)jdk、jmeter、ant

安装步骤不再详述,解压完成后都需要配置环境变量,只要环境变量配置不出问题,都是可以正常使用的。

注:jmeter还需要下载2个插件,JMeterPlugins-Extras-1.4.0和JMeterPlugins-Standard-1.4.0,复制到jmeter安装路径的libext目录下。

(二)Jenkins

Windows系统下一键安装Jenkins即可(Linux环境下搭建jenkins请参看Jenkins官方的部署文档),安装成功后需注意:

1、jenkins服务默认端口为8080,如与其他服务冲突,可在安装路径..jenkinsjenkins.xml中修改默认端口,如下方的8080改为未被其他服务占用的端口:

<executable>%BASE%jreinjava</executable>  
  <arguments>-Xrs -Xmx256m -Dhudson.lifecycle=hudson.lifecycle.WindowsServiceLifecycle -jar "%BASE%jenkins.war" --httpPort=8080 --webroot="%BASE%war"</arguments>

2、第一次打开可能要解锁jenkins,在安装路径..jenkinssecrets下找到initialAdminPassword文件复制密码输入到password输入框(网页上也会有路径提示),点击continue即可进行下一步操作。

3、打开jenkins,首次进入需要先安装插件。进入首页后点击系统管理,然后在右侧选择管理插件,下载后续需要用到的4个插件:

Performance Plugin、Email Extension、Email Extension Template Plugin、HTML Publisher plugin

三、用ant构建运行Jmeter脚本并生成jtl、html格式报告

(一)修改jmeter格式文件

jmeter默认保存的是.csv格式文件,因此需要把默认的进行修改,在jmeter的安装路径下找到bin/jmeter.properties文件,修改#jmeter.save.saveservice.output_format=csv为jmeter.save.saveservice.output_format=xml;

(二)修改jmeter安装路径

将jmeter安装路径的..extrasant-jmeter-1.1.1.jar文件拷贝到ant安装路径的lib目录下;

(三)配置build.xml文件

1、新建一个专门存放报告的report目录;

2、新建一个专门存放脚本的目录,每次要运行哪个目录的脚本,需要去修改build.xml文件脚本文件目录;

3、将jmeter安装路径..extras目录下的build.xml文件和下载好的jmeter.results.shanhe.me.xsl文件复制到新建的report目录下;(注:jmeter中自带的样式文件为jmeter-results-detail-report_21.xsl,这里替换成一个样式更好的文件

4、修改build.xml,代码如下:

<?xml version="1.0" encoding="UTF-8"?>  
    <project name="ant-jmeter-test" default="run" basedir=".">  
        <tstamp>  
            <format property="time" pattern="yyyyMMddHHmm" />  
        </tstamp>  
        <!-- 本地存放报告的路径-->
        <property name="basedirectory" value="E:......" />
        <!-- 本地存放脚本的路径-->
        <property name="scriptdirectory" value="E:......" />        
        <!-- 需要改成自己本地的 Jmeter 目录-->    
        <property name="jmeter.home" value="E:......" />  
        <!-- jmeter生成jtl格式的结果报告的路径-->   
        <property name="jmeter.result.jtl.dir" value="{{basedirectory}" />  
        <!-- jmeter生成html格式的结果报告的路径-->  
        <property name="jmeter.result.html.dir" value="{{basedirectory}" />  
        <!-- Name of test (without .jmx) -->  
        <property name="test" value="Test"/>  
        <!-- 生成的报告的前缀-->    
        <property name="ReportName" value="TestReport" />  
        <property name="jmeter.result.jtlName" value="{{jmeter.result.jtl.dir}/{{test}{{time}.jtl" />  
        <property name="jmeter.result.htmlName" value="{{jmeter.result.html.dir}/{{test}{{time}.html" />  
        <!-- 同一个测试脚本生成的报告名一样,假如想每次报告名都不一样,可以把报告名后缀前加上{{time},这样生成的文件就会加上报告时间(精确到分)--> 
        <path id="xslt.classpath">  
            <fileset dir="{{jmeter.home}/lib" includes="xalan*.jar"/>  
            <fileset dir="{{jmeter.home}/lib" includes="serializer*.jar"/>  
        </path>  
        <target name="run">  
            <antcall target="test" />  
            <antcall target="report" />  
        </target>  
        <target name="test">  
            <taskdef name="jmeter" classname="org.programmerplanet.ant.taskdefs.jmeter.JMeterTask" />  
        <jmeter jmeterhome="{{jmeter.home}" resultlog="{{jmeter.result.jtlName}">  
                 <!-- 声明要运行的脚本。"*.jmx"指包含此目录下的所有jmeter脚本-->  
                <testplans dir="{{scriptdirectory}" includes="{{test}.jmx" />  
            </jmeter>  
        </target>  
        <target name="report">  
            <tstamp> <format property="report.datestamp" pattern="yyyy/MM/dd HH:mm" /></tstamp>  
            <xslt classpathref="xslt.classpath"  
                  force="true"  
                  in="{{jmeter.result.jtlName}"  
                  out="{{jmeter.result.htmlName}"  
                  style="{{basedirectory}/jmeter.results.shanhe.me.xsl ">  
                  <param name="dateReport" expression="{{report.datestamp}"/>  
            </xslt>  
            <copy todir="{{jmeter.result.html.dir}">  
                <fileset dir="{{jmeter.home}/extras">  
                    <include name="collapse.png" />  
                    <include name="expand.png" />  
                </fileset>  
            </copy>  
        </target>  
</project>

注:第一行必须顶格;build.xml里的地址带有特殊符号(中文、下划线之类的),运行时就会报错,需要把目录都变为纯英文和数字的

(四)执行命令开始构建

Windows系统下使用命令行或者别的工具,进入创建的report目录后,执行ant.bat -file build.xml -Dtest=脚本文件名(不需要后缀),在这个目录生成jtl和html文件就说明构建成功了;

Linux下命令为ant -file build.xml -Dtest=脚本文件名(不需要后缀)。

四、配置测试报告样式

默认配置的样式,报告中只有错误多少,没有错误的详细信息,因此把样式进行优化,修改jmeter.properties文件如下部分,执行完脚本后就会保存这些结果到.jtl文件里面:

jmeter.save.saveservice.data_type=true
jmeter.save.saveservice.label=true
jmeter.save.saveservice.response_code=true
#response_data is not currently supported for CSV output
jmeter.save.saveservice.response_data=true
#Save ResponseData for failed samples
jmeter.save.saveservice.response_data.on_error=false
jmeter.save.saveservice.response_message=true
jmeter.save.saveservice.successful=true
jmeter.save.saveservice.thread_name=true
jmeter.save.saveservice.time=true
jmeter.save.saveservice.subresults=true
jmeter.save.saveservice.assertions=true
jmeter.save.saveservice.latency=true
jmeter.save.saveservice.connect_time=true
jmeter.save.saveservice.samplerData=true
jmeter.save.saveservice.responseHeaders=true
jmeter.save.saveservice.requestHeaders=true
jmeter.save.saveservice.encoding=false
jmeter.save.saveservice.bytes=true
jmeter.save.saveservice.url=true
jmeter.save.saveservice.filename=true
jmeter.save.saveservice.hostname=true
jmeter.save.saveservice.thread_counts=true
jmeter.save.saveservice.sample_count=true
jmeter.save.saveservice.idle_time=true

五、配置jenkins

(一)Jenkins全局工具配置

打开jenkins页面,点击系统管理,然后在右侧点击全局工具配置,需要配置安装在本地的JDK和ANT的路径;

JDK安装:输入jdk版本和jdk的安装路径,请参考下图:

ANT安装:输入ant版本和ant的安装路径,请参考下图:

(二)jenkins邮件配置

1、将Jenkins Location的url改成静态IP。Jenkins URL有默认值,但是最好修改,默认地址不安全。系统管理员邮件地址也一定要写,否则所发邮件会变为垃圾邮件;

2、扩展电子邮件通知配置,参考下图(注:这里一定要配置STMP认证,不然收不到jenkins发送的带模版的邮件):

SMTP server的填写需要和要配置的邮箱互相匹配,如QQ邮箱就是:smtp.qq.com

Use SMTP Authentication需要勾选上,User Name需要填写上一步中的管理员邮箱,

password需要对应的邮箱开启POP3服务,开启后会得到一串密码,将密码填写到password中;

进入到邮箱的设置--账户--POP3服务开启;

Default Content Type仍然填写管理员邮箱。

3、邮件通知的配置与上一步相同(SMTP认证一定要填),不再详述,参考下图:

六、新建Item构建项目

(一)新建Item

新建一个Item,点击左侧栏的新建任务,选择构建一个自由风格的软件项目,并根据实际,输入项目名称(若是后续使用,可以选择复制已有的Item,然后进行一些修改),点击ok,进入项目配置页面(注:所有的配置,都要注意该项下方或右方是否有高级选项,有的话都点开看看是否需要配置):

(二)丢弃旧的构建

需要勾选“丢弃旧的构建”,不然每次构建数据都保存,浪费储存空间,这里保留的个数和天数的数值,根据需要填写:

(三)参数化构建过程

构建时,可能每次构建使用的脚本都不一样,因此把脚本名称参数化,这样会比较方便,具体步骤为:

1、勾选参数化构建过程;

2、点击添加参数按钮,选择选项参数;

3、名称为参数名,选项是脚本名,一行一个值,可以多行,构建时直接选择就行,描述是这些参数和值的描述;

4、把下面所有用到这个参数testscript的地方,都用 {{testscript}代替,以后想换脚本,直接在参数值处添加或更换就行,不用动其他地方,参数化后用起来很方便;

(四)自定义工作空间

高级项目选项,点击参数化构建过程下的高级按钮展开,此处选择使用自定义的工作空间,该路径是build.xml文件的根目录:

(五)构建触发器--定时构建

可根据需求选择,因为要做接口自动化,每天定时跑任务并监控,所以这里选择的是Build periodically(定期构建),注意:关于定期构建参数的说明:"* * * * *",总共有5个参数,分别代表分(0~59)、时(0~23)、天(1~31)、月(1~12)、周(0~7,0和7表示星期天):

a、每十五分钟(也许在:07,:22,:37,:52)

H/15 ****


b、每小时上半场每十分钟一班(三次,也许是:04,:14,:24)

H(0-29/10 ****


c、从上午9:45开始每小时45分钟,每个工作日下午3:45结束,每两小时一次。

45 9-16/2 * * 1-5


d、每个工作日上午9点到下午5点之间,每两小时一次(也许在上午10:38,下午12:38,下午2:38,下午4:38)

HH(9-16)/2 * * 1-5


e、12月份以外的每月1日和15日每天一次

HH 1,15 1-11 *


每隔5分钟构建一次

H/5 * * * *


每两小时构建一次

H H/2 * * *


每天中午12点定时构建一次

H 12 * * *


每天下午18点定时构建一次

H 18 * * *


在每个小时的前半个小时内的每10分钟

H(0-29)/10 * * * *


每两小时45分钟,从上午9:45开始,每天下午3:45结束

45 9-16/2 * * 1-5


每两小时一次,每个工作日上午9点到下午5点(也许是上午10:38,下午12:38,下午2:38,下午4:38)

H H(9-16)/2 * * 1-5

(六)增加构建步骤--执行命令

此处需要在命令处,添加删除jtl或html的命令,若是想保留所有的jtl和html,则可以不添加删除命令,Windows选择执行Windows批处理命令,Linux选择执行shell:

Windows使用的是bat脚本,用于删除指定目录里存在的报告,这里的语法,引用参数格式为:%参数名%;模糊匹配格式:**.html(所有html格式的文件):

del "报告存放的路径"%testscript%**.jtl  

del "报告存放的路径"%testscript%**.html

Linux使用的命令如下,可指定脚本名进行模糊匹配:

rm -f  /home/workspace/report/jtl/脚本名*.jtl

rm -f  /home/workspace/report/html/脚本名*.html

注:执行命令一定要放在其他构建步骤之前,构建步骤是按照页面上的排序来执行的,如果放在invoke ant之后的话,会删除掉所有构建完后生成的jtl、html文件,此时构建就会失败;鼠标点击构建步骤左上角后可以拖动排序。

(七)增加构建步骤--Invoke Ant

在ant version处,选择之前本地安装的ant版本即可;右侧点击高级按钮展开页面,在build file处填写build.xml文件的路径,在Properties中填写test=xxxx,xxxx是指脚本文件的名字;由于将脚本参数化了,所以此处直接填写test={testscript:

(八)增加构建后操作--归档成品

用于存档的文件填写/.html,模糊匹配html文件,也可以写上具体的文件名如:**/XXX.html;

(九)增加构建后操作--Publish HTML reports

HTML directory to archive处填写html的目录,也可不填写;index page(s)可以写成*.html,也可以写上具体的文件名,但写具体的文件名后期得改,不方便,参数化以后写成:{{testscript}*.html 这样在Jenkins的项目中,就会出现一个HTML样式测试报告的菜单,点击可在Jenkins中直接预览测试报告

点击后可以跳转到html详情页面

(十)增加构建后操作--Publish Performance test result report

Source data files (autodetects format)指jtl源文件,/xxx.jtl,这里xxx与jmx脚本文件名一致;参数化后,模糊匹配可填写为:/{{testscript}.jtl,也可以全匹配写为:/{{testscript}.jtl;下方还有一个错误比例,现在设置的是0-100,即不管错多少都发邮件,这个可以根据项目的实际情况来进行自定义,其他设置默认即可,具体设置如下图:

配置后可以在页面上看到Performance Trend的图表:

(十一)增加构建后操作-- E-mail Notification

当构建不稳定或者失败时会通知收件人,收件人邮箱以空格进行分隔

(十二)增加构建后操作--Editable Email Notification

基础设置可以先不用配置,找到右下方的Advance Settings按钮,点击后展开后找到Trigger,点击Add,增加触发器(这个地方才真正控制发邮件的地方);

目前常用的是每次测试的执行结果发送给测试,接口测试执行异常时,结果发送至研发人员和测试,所以可添加Always和Failure-Any两种触发器,点击每个触发器下方的高级按钮,展开的菜单下,填写邮件的各项内容即可(两种触发器都要填,分别填需要发送人员的邮箱,邮件发给多个人时,在Recipient List栏添加多个邮箱,每个邮箱之间以英文逗号“,”隔开);以Always为例,如下图:

这里将Content Type改为HTML格式,我们的邮件正文就能呈HTML格式显示,邮件标题随意设置,邮件正文内容如下,将其粘content中即可,也可根据需要自己编写、修改:

<!DOCTYPE html>  
<html>  
<head>  
<meta charset="UTF-8">  
<title>{{PROJECT_NAME}-第{{BUILD_NUMBER}次构建日志</title>  
</head>  
<body leftmargin="8" marginwidth="0" topmargin="8" marginheight="4"  
    offset="0">  
    <table width="95%" cellpadding="0" cellspacing="0"  
        style="font-size: 11pt; font-family: Tahoma, Arial, Helvetica, sans-serif">  
        <tr>  
            <td>(本邮件是程序自动下发的,请勿回复!)</td>  
        </tr>  
        <tr>  
            <td><h2>  
                    <font color="#0000FF">构建结果 - {{BUILD_STATUS}</font>  
                </h2></td>  
        </tr>  
        <tr>  
            <td><br />  
            <b><font color="#0B610B">构建信息</font></b>  
            <hr size="2" width="100%" align="center" /></td>  
        </tr>  
        <tr>  
            <td>  
                <ul>  
                    <li>项目名称 : {{PROJECT_NAME}</li>  
                    <li>构建编号 : 第{{BUILD_NUMBER}次构建</li>  
                    <li>触发原因 : {{CAUSE}</li>  
                    <li>构建日志 : <a href="{{BUILD_URL}console">{{BUILD_URL}console</a></li>  
                    <li>工作目录 : <a href="{{PROJECT_URL}ws">{{PROJECT_URL}ws</a></li>  
                    <li>构建  Url : <a href="{{BUILD_URL}">{{BUILD_URL}</a></li>  
                    <li>项目  Url : <a href="{{PROJECT_URL}">{{PROJECT_URL}</a></li>  
                </ul>  
            </td>  
        </tr>  
        <tr>  
            <td><b><font color="#0B610B">Changes Since Last  
                        Successful Build:</font></b>  
            <hr size="2" width="100%" align="center" /></td>  
        </tr>  
        <tr>  
            <td>  
                <ul>  
                    <li>历史变更记录 : <a href="{{PROJECT_URL}changes">{{PROJECT_URL}changes</a></li>  
                </ul> {{CHANGES_SINCE_LAST_SUCCESS,reverse=true, format="Changes for Build #%n:<br />%c<br />",showPaths=true,changesFormat="<pre>[%a]<br />%m</pre>",pathFormat="    %p"}  
            </td>  
        </tr>  
        <tr>  
            <td><b>Test Informations</b>  
            <hr size="2" width="100%" align="center" /></td>  
        </tr>  
        <tr>  
            <td><pre  
                    style="font-size: 11pt; font-family: Tahoma, Arial, Helvetica, sans-serif">Total:{{TEST_COUNTS,var="total"},Pass:{{TEST_COUNTS,var="pass"},Failed:{{TEST_COUNTS,var="fail"},Skiped:{{TEST_COUNTS,var="skip"}</pre>  
                <br /></td>  
        </tr>  
        <tr>  
            <td><b><font color="#0B610B">构建日志 (最后 100行):</font></b>  
            <hr size="2" width="100%" align="center" /></td>  
        </tr>  
        <tr>  
            <td><textarea cols="80" rows="30" readonly="readonly"  
                    style="font-family: Courier New">{{BUILD_LOG, maxLines=100}</textarea>  
            </td>  
        </tr>  
    </table>  
</body>  
</html>

在Attachments中填写需要发送的附件名称,构建文件夹下的文件都能当成邮件附件去发送,这里将测试报告名字填入框中即可,写成/脚本名.html,也可用参数化+模糊匹配:/{{testscript}.html,如下图:

设置完上述所以东西后,就可以开始构建了。

七、构建项目

项目配置好以后,点击新建的Item名称,就可以构建了:

(一)无参数化

没有参数化,构建时,点击左侧的立即构建按钮,就开始构建了;

(二)参数化

参数化了,立即构建按钮就变为下图build with parameters参数构建了,点击参数构建,右方会出来参数列表,选择需要构建的参数值,就能选中脚本直接构建了;

构建时,有可能会报错,可返回检查一下系统设置和项目配置有没有配置错误,或者去控制台输出中查看日志,定位问题再逐一解决

八、遇到的问题及解决方法

(一)Windows系统下可能遇到的问题

Windows系统下在Jenkins上直接预览测试报告时,发现报告的详情无法查看,或是报告的样式有误,可参考jenkins官方文档:

https://wiki.jenkins.io/display/JENKINS/Configuring+Content+Security+Policy

1、暂时解决方案,也是最简单的解决方案,就是在Jenkins的系统管理-脚本命令行,输入下面的命令,手动执行2次,看到返回Result后,再构建就可以直接预览报告了,但是重启或关闭jenkins服务后需要再次手动执行这个命令才能查看报告详情

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

注:在更改要更改的行为的系统属性后,可能需要强制对受影响的Web页面进行未缓存的重新加载(“Shift-F5”或等效)

2、永久解决方案,方法是修改jenkisn目录下的jenkins.xml文件,把端口这一行代表替换为下方的代码:


<arguments>-Xrs -Xmx256m -Dhudson.model.DirectoryBrowserSupport.CSP= -Dhudson.lifecycle=hudson.lifecycle.WindowsServiceLifecycle -jar "%BASE%jenkins.war" --httpPort=8080 --webroot="%BASE%war"</arguments>

(二)Linux系统下可能遇到的问题

Linux系统下无法查看报告详情或报告样式有误的解决办法(同上可以参考官方文档):

1、通过systemctl status jenkins 查看jenkins的启动脚本文件位置

[root@localhost ~]# systemctl status jenkins
● jenkins.service - LSB: Jenkins Continuous Integration Server
Loaded: loaded (/etc/rc.d/init.d/jenkins; bad; vendor preset: disabled)
......
......
......

2、进入后查看jenkins的启动文件,可以查到jenkins配置文件所在位置。

vim /etc/rc.d/init.d/jenkins
/JENKINS_CONFIG
/etc/sysconfig/jenkins

3、进入配置文件所在位置

vim /etc/sysconfig/jenkins

进入后增加环境变量

HUDSON_OPTIONS="-Dhudson.model.DirectoryBrowserSupport.CSP="

4、再次进入jenkins启动文件,修改代码,增加HUDSON_OPTIONS变量

vim /etc/rc.d/init.d/jenkins
JAVA_CMD="{JENKINS_JAVA_CMD {JENKINS_JAVA_OPTIONS -DJENKINS_HOME={JENKINS_HOME {HUDSON_OPTIONS -jar {JENKINS_WAR"
PARAMS="--logfile=/var/log/jenkins/jenkins.log --webroot=/var/cache/jenkins/war --daemon"

5、重启Jenkins服务,使配置生效。

services jenkins restart

6、进入到jenkins的系统管理->脚本命令行,输入下面的命令,手动执行2次,看到返回Result后即可,不受重启、关机等因素的影响:

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

(三)Linux系统下权限问题

新建的jmeter目录、ant目录、jmeter脚本目录、工作空间(build.xml文件所在的目录)目录及目录下的所有内容全部开放最大权限,命令为chmod -R 777 /...  不开放权限的话构建会报错;

(四)Linux系统下在jenkins构建完成后HTML报告无内容;jmeter可以运行脚本,但是查看jmeter.log日志报错空指针异常,jmeter.save.SaveService.saveSampleResult报错,查看log.jtl不展示聚合报告内容:

1、jmeter可以运行脚本,但是jmeter.log报错解决办法:

编辑jmeter工具bin目录下的jmeter.properties,在之前的步骤中我们将#jmeter.save.saveservice.output_format=csv改成了jmeter.save.saveservice.output_format=xml,现在再改回去,改成jmeter.save.saveservice.output_format=csv,编辑完成后再次运行jmeter脚本,命令为# jmeter -n -t /脚本路径/脚本名称.jmx -l log.jtl;

2、脚本运行完成后再次查看log.jtl日志,此时如果仍不显示聚合报告,再去查看jmeter.log,会报错java.net.UnknownHostException: XXX: XXX: Name or service not known,也就是说无法解析主机,修改办法如下:

输入命令vim /etc/hosts

localhost开头的行的末尾加上XXX,即报错信息中的XXX地址,下如图,localhost.node1是之前遇到的报错的地址,配置进去就可以了

3、完成上述两步后,再次运行jmeter脚本,运行完成后查看log.jtl和jmeter.log日志,此时报错应该全部解决了;然后我们再次编辑jmeter工具bin目录下的jmeter.properties,将jmeter.save.saveservice.output_format=csv改成jmeter.save.saveservice.output_format=xml

4、在jenkins中构建项目,构建完成后生成的HTML文件的详情也可以查看了。

(五)在jenkins项目的配置中,构建时的步骤一定要按照执行的顺序来进行排放,不然会导致构建失败。例如执行Windows的命令:删除之前生成的jtl和html文件,如果放在Invoke Ant之后的话,就会删除掉刚刚ant生成的jtl和html文件,使后续的构建后操作找不到jtl和html文件,就会报错,一定要注意!但是构建后的操作不分先后,顺序可以随意排放;

(六)Windows下的jmeter一定要和Linux系统下的jmeter的版本保持一致,不然会出现脚本文件不兼容的情况,在运行脚本时报错。

九、还需要优化的地方

1、收到的邮件中的附件,不能直接通过预览的方式查看附件的详情,必须要下载下来才能查看。

2、目前还没对jmeter脚本做版本控制,后续要将脚本维护到svn或者是git上。