Ant+JMeter+WebDriverAgent 游记

0. 前言

上周末看到了一篇 WebDriverAgent 踩坑记 , 把我导向了一个月前的 WebDriverAgent 简介 ,才看到我在那的评论被回复了。说起来我的提醒被匿名用户刷屏没看到,现在看到了就打算填个坑,小试一下。 而最近 Ant + JMeter + * 的模式有点火,于是我也来凑个热闹,多加一个 Ant。本文从社区里的其他文章里面吸收了不少经验,列在文中,感谢社区。

1. 安装

Ant, JMeter 都不需要安装,解压即用,非常方便。好消息是JMeter3发布,最实用的莫过于 jsonpath 了,提取json的response就方便多了。
WebDriverAgent的安装也是比较简单的,安装官网https://github.com/facebook/WebDriverAgent README 即可,或者参看https://testerhome.com/topics/4904 。记录一下我遇到的几个小问题:
* 直接 brew install carthage 的时候提示我需要 XCode7.3 ,搜索下载 carthage.pkg 安装成功解决了。
* 下载完WebDriverAgent项目后,执行xcodebuild命令提示找不到模拟器,手动启动了模拟器仍然不行,最后只好在XCode里面打开项目选择执行,就成功了。成功一次之后,以后就都可以用命令启动了,我写成了start.sh,方便使用。
* 编译的过程中提示未知的编译选项 -Wno-double-promotion,打开WebDriverAgent/XCTWebDriverAgentLib/Commands/FBCustomCommands.m文件,去掉了最后的-Wno-double-promotion选项,就这样解决了。

2. JMeter脚本

我把 https://github.com/facebook/WebDriverAgent/wiki/Queries 里面提到的内容都转化成了取样器,放在“工作台”中了,需要的用什么方法只要复制一个出来改改就能用。xml文件太长就不放代码了直接在尾部下载去吧。

被测端选用了Appium提供的TestApp,简单地跑了几个加法和一个Alert,也算走了一遍流程。有几点说明的:
* 将HOST、PORT、bundleId等全局的配置放到了顶部方便修改和调整
* WebDriverAgent需要的Header Content-Type: application/json直接放在的一个全局的请求头管理器里面了,后面不用再理会
* HTTP请求大部分是一样的,除了数据和URI以及部分超时设置,所以也做成全局的HTTP请求默认值了
* 断言成功用正则判断响应里面status=0,有个坑就是如果查找元素失败,返回空数组但状态还是0,需要注意
* 如果已经安装TestApp,用bundleId启动就好,否则直接用*.app来制定,切换取样器即可
* 在setUp线程启动App获得session后,为了跨线程传递session,用BeanShell将它放进了properties里了,可以在tearDown线程进行关闭
* 启动App的过程有点长,需要将HTTP请求的read时间设置长一点避免超时
* 本来应该使用csv来管理测试数据的,但为了少带文件并且涉及路径,这里用forEach代替了。应该用csv+循环控制器才是好的实现

3. Ant脚本和结果style文件

从下列文章里直接借鉴(抄袭)来的:
Jenkins+Jmeter+Ant 接口持续集成 https://testerhome.com/topics/5186
jmeter 报告扩展样式优化 (接口版+性能版) https://testerhome.com/topics/5252
对 Jenkins+ANT+Jmeter 接口测试的实践 https://testerhome.com/topics/5262
修改点:
* 增加了clean过程,否则多次执行会将新结果append到旧结果中,造成混乱
* 保持JMeter本身环境的纯净,不修改JMeter目录下的任何配置,而是将执行过程中的properties直接写到了build.xml中

<code><span class="cp"><?xml version="1.0" encoding="UTF-8"?></span>

<span class="nt"><project</span> <span class="na">name=</span><span class="s">"ant-jmeter-test"</span> <span class="na">default=</span><span class="s">"all"</span> <span class="na">basedir=</span><span class="s">"."</span><span class="nt">></span>
    <span class="c"><!-- 需要改成自己本地的 Jmeter 目录--></span>  
    <span class="nt"><property</span> <span class="na">name=</span><span class="s">"jmeter.home"</span> <span class="na">value=</span><span class="s">"D:/Program Files/apache-jmeter-3.0"</span> <span class="nt">/></span>
    <span class="c"><!-- 声明要运行的脚本。"*.jmx"指包含此目录下的所有jmeter脚本--></span>
    <span class="nt"><property</span> <span class="na">name=</span><span class="s">"jmeter.testplans.dir"</span> <span class="na">value=</span><span class="s">"E:/ant_jmeter_wda/testplans"</span> <span class="nt">/></span>
    <span class="c"><!-- jmeter生成jtl格式的结果报告的路径--></span> 
    <span class="nt"><property</span> <span class="na">name=</span><span class="s">"jmeter.result.jtl.dir"</span> <span class="na">value=</span><span class="s">"E:/ant_jmeter_wda/results"</span> <span class="nt">/></span>
    <span class="c"><!-- jmeter生成html格式的结果报告的路径--></span>
    <span class="nt"><property</span> <span class="na">name=</span><span class="s">"jmeter.result.html.dir"</span> <span class="na">value=</span><span class="s">"E:/ant_jmeter_wda/results"</span> <span class="nt">/></span>
    <span class="c"><!-- jmeter生成html格式的结果报告的模板--></span> 
    <span class="nt"><property</span> <span class="na">name=</span><span class="s">"jmeter.result.style.dir"</span> <span class="na">value=</span><span class="s">"E:/ant_jmeter_wda/style"</span> <span class="nt">/></span>
    <span class="c"><!-- 生成的报告的前缀--></span>  
    <span class="nt"><property</span> <span class="na">name=</span><span class="s">"ReportName"</span> <span class="na">value=</span><span class="s">"TestReport"</span> <span class="nt">/></span>
    <span class="nt"><property</span> <span class="na">name=</span><span class="s">"jmeter.result.jtlName"</span> <span class="na">value=</span><span class="s">"${jmeter.result.jtl.dir}/report.jtl"</span> <span class="nt">/></span>
    <span class="nt"><property</span> <span class="na">name=</span><span class="s">"jmeter.result.htmlName"</span> <span class="na">value=</span><span class="s">"${jmeter.result.html.dir}/report-details.html"</span> <span class="nt">/></span>        
    <span class="nt"><property</span> <span class="na">name=</span><span class="s">"lib.dir"</span> <span class="na">value=</span><span class="s">"${jmeter.home}/lib"</span><span class="nt">/></span>

    <span class="nt"><path</span> <span class="na">id=</span><span class="s">"xslt.classpath"</span><span class="nt">></span>
        <span class="nt"><fileset</span> <span class="na">dir=</span><span class="s">"${lib.dir}"</span> <span class="na">includes=</span><span class="s">"xalan-*.jar"</span><span class="nt">/></span>
        <span class="nt"><fileset</span> <span class="na">dir=</span><span class="s">"${lib.dir}"</span> <span class="na">includes=</span><span class="s">"serializer-*.jar"</span><span class="nt">/></span>
    <span class="nt"></path></span>

    <span class="nt"><target</span> <span class="na">name=</span><span class="s">"all"</span><span class="nt">></span>
        <span class="nt"><antcall</span> <span class="na">target=</span><span class="s">"clean"</span> <span class="nt">/></span>
        <span class="nt"><antcall</span> <span class="na">target=</span><span class="s">"run"</span> <span class="nt">/></span>
        <span class="nt"><antcall</span> <span class="na">target=</span><span class="s">"report"</span> <span class="nt">/></span>
        <span class="nt"><antcall</span> <span class="na">target=</span><span class="s">"xslt-report"</span> <span class="nt">/></span>
    <span class="nt"></target></span>

    <span class="nt"><target</span> <span class="na">name=</span><span class="s">"clean"</span><span class="nt">></span>
        <span class="nt"><delete</span> <span class="na">file=</span><span class="s">"${jmeter.result.jtlName}"</span><span class="nt">/></span>
    <span class="nt"></target></span>

    <span class="nt"><target</span> <span class="na">name=</span><span class="s">"run"</span><span class="nt">></span>
        <span class="nt"><taskdef</span> <span class="na">name=</span><span class="s">"jmeter"</span> <span class="na">classname=</span><span class="s">"org.programmerplanet.ant.taskdefs.jmeter.JMeterTask"</span> <span class="nt">/></span>
        <span class="nt"><jmeter</span> <span class="na">jmeterhome=</span><span class="s">"${jmeter.home}"</span> <span class="na">resultlog=</span><span class="s">"${jmeter.result.jtlName}"</span><span class="nt">></span>
            <span class="nt"><testplans</span> <span class="na">dir=</span><span class="s">"${jmeter.testplans.dir}"</span> <span class="na">includes=</span><span class="s">"*.jmx"</span> <span class="nt">/></span>

            <span class="nt"><property</span> <span class="na">name=</span><span class="s">"jmeter.save.saveservice.output_format"</span> <span class="na">value=</span><span class="s">"xml"</span><span class="nt">/></span>
            <span class="nt"><property</span> <span class="na">name=</span><span class="s">"jmeter.save.saveservice.response_data"</span> <span class="na">value=</span><span class="s">"true"</span><span class="nt">/></span>
            <span class="nt"><property</span> <span class="na">name=</span><span class="s">"jmeter.save.saveservice.samplerData"</span> <span class="na">value=</span><span class="s">"true"</span><span class="nt">/></span>
            <span class="nt"><property</span> <span class="na">name=</span><span class="s">"jmeter.save.saveservice.responseHeaders"</span> <span class="na">value=</span><span class="s">"true"</span><span class="nt">/></span>
            <span class="nt"><property</span> <span class="na">name=</span><span class="s">"jmeter.save.saveservice.requestHeaders"</span> <span class="na">value=</span><span class="s">"true"</span><span class="nt">/></span>
            <span class="nt"><property</span> <span class="na">name=</span><span class="s">"jmeter.save.saveservice.encoding"</span> <span class="na">value=</span><span class="s">"true"</span><span class="nt">/></span>
            <span class="nt"><property</span> <span class="na">name=</span><span class="s">"jmeter.save.saveservice.url"</span> <span class="na">value=</span><span class="s">"true"</span><span class="nt">/></span>
            <span class="nt"><property</span> <span class="na">name=</span><span class="s">"jmeter.save.saveservice.filename"</span> <span class="na">value=</span><span class="s">"true"</span><span class="nt">/></span>
            <span class="nt"><property</span> <span class="na">name=</span><span class="s">"jmeter.save.saveservice.hostname"</span> <span class="na">value=</span><span class="s">"true"</span><span class="nt">/></span>
            <span class="nt"><property</span> <span class="na">name=</span><span class="s">"jmeter.save.saveservice.thread_counts"</span> <span class="na">value=</span><span class="s">"true"</span><span class="nt">/></span>
            <span class="nt"><property</span> <span class="na">name=</span><span class="s">"jmeter.save.saveservice.sample_count"</span> <span class="na">value=</span><span class="s">"true"</span><span class="nt">/></span>
            <span class="nt"><property</span> <span class="na">name=</span><span class="s">"jmeter.save.saveservice.idle_time"</span> <span class="na">value=</span><span class="s">"true"</span><span class="nt">/></span>
            <span class="nt"><property</span> <span class="na">name=</span><span class="s">"jmeter.save.saveservice.assertion_results"</span> <span class="na">value=</span><span class="s">"all"</span><span class="nt">/></span>
            <span class="nt"><property</span> <span class="na">name=</span><span class="s">"jmeter.save.saveservice.bytes"</span> <span class="na">value=</span><span class="s">"true"</span><span class="nt">/></span>
            <span class="nt"><property</span> <span class="na">name=</span><span class="s">"file_format.testlog"</span> <span class="na">value=</span><span class="s">"${format}"</span><span class="nt">/></span>
            <span class="nt"><property</span> <span class="na">name=</span><span class="s">"jmeter.save.saveservice.response_data.on_error"</span> <span class="na">value=</span><span class="s">"${funcMode}"</span><span class="nt">/></span>

        <span class="nt"></jmeter></span>
    <span class="nt"></target></span>

    <span class="nt"><target</span> <span class="na">name=</span><span class="s">"xslt-report"</span><span class="nt">></span>
        <span class="nt"><tstamp><format</span> <span class="na">property=</span><span class="s">"report.datestamp"</span> <span class="na">pattern=</span><span class="s">"yyyy/MM/dd HH:mm"</span><span class="nt">/></tstamp></span>
        <span class="nt"><xslt</span>
            <span class="na">classpathref=</span><span class="s">"xslt.classpath"</span>
            <span class="na">force=</span><span class="s">"true"</span>
            <span class="na">in=</span><span class="s">"${jmeter.result.jtlName}"</span>
            <span class="na">out=</span><span class="s">"${jmeter.result.html.dir}/report-summary.html"</span>
            <span class="na">style=</span><span class="s">"${jmeter.result.style.dir}/jmeter-results-detail-report_21.xsl"</span><span class="nt">></span>
            <span class="nt"><param</span> <span class="na">name=</span><span class="s">"dateReport"</span> <span class="na">expression=</span><span class="s">"${report.datestamp}"</span><span class="nt">/></span>
        <span class="nt"></xslt></span>
    <span class="nt"></target></span>

    <span class="nt"><target</span> <span class="na">name=</span><span class="s">"report"</span><span class="nt">></span>
        <span class="nt"><xslt</span> <span class="na">classpathref=</span><span class="s">"xslt.classpath"</span>
            <span class="na">force=</span><span class="s">"true"</span>
            <span class="na">in=</span><span class="s">"${jmeter.result.jtlName}"</span>
            <span class="na">out=</span><span class="s">"${jmeter.result.htmlName}"</span>
            <span class="na">style=</span><span class="s">"${jmeter.result.style.dir}/jmeter-results-shanhe-me.xsl"</span><span class="nt">></span>
            <span class="c"><!-- 因为上面生成报告的时候,不会将相关的图片也一起拷贝至目标目录,所以,需要手动拷贝 --></span> 
            <span class="nt"><param</span> <span class="na">name=</span><span class="s">"showData"</span> <span class="na">expression=</span><span class="s">"${show-data}"</span><span class="nt">/></span>
        <span class="nt"></xslt></span>
        <span class="nt"><copy</span> <span class="na">todir=</span><span class="s">"${jmeter.result.html.dir}"</span><span class="nt">></span>
            <span class="nt"><fileset</span> <span class="na">dir=</span><span class="s">"${jmeter.home}/extras"</span><span class="nt">></span>
                <span class="nt"><include</span> <span class="na">name=</span><span class="s">"collapse.png"</span> <span class="nt">/></span>
                <span class="nt"><include</span> <span class="na">name=</span><span class="s">"expand.png"</span> <span class="nt">/></span>
            <span class="nt"></fileset></span>
        <span class="nt"></copy></span>
    <span class="nt"></target></span>
<span class="nt"></project></span></code>

4. 执行结果展示

Ant执行界面


手机端动作

结果摘要(右上角可跳转到详情)


结果详情



5. 下载

文件很小,整个jpg也才41K所以就直接这样上传了。
里面有一个python文件可以用来解析base64的截屏。
testplans里面有一个TestPlan.jmx1,用的是东哥的服务,重命名去掉最后的1也可以执行,拿去玩吧。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值