测量webView页面性能(使用UiAutomator和性能监控工具)
背景:
俺双11会场测试的总指挥想要确认,在猫客的webview中填多少坑位合适,所以进行了如下操作并获取性能:
1,进入webview页面滑动到底部,然后再快速回到顶部,
2,点击顶部的banner进入下级页面,
3,页面深度3层,即重复1,2该操作3次。
采用的技术
需求拆分为2部分,webview控制脚本和性能监控。
脚本 UiAutomator
因为猫客的自动化采用UiAutomator实现,已经提供了很多封装方法,修改起来比较快。
缺点: UiAutomator 不能识别webview的元素,所以判断滑动到底部,滑动到顶部,点击顶部banner这几个操作难点需要突破。
性能数据采集
有3种方案:
1,猫客内嵌入了性能测试模块,打包时配置MONITOR_OPEN=true,然后让监控开启即可。不方便之处是不能实时显示
2,请参见 http://blog.csdn.net/kittyboy0001/article/details/47317855
3, 安装易测客户端或者其他第三方能够监控性能的app或者工具取数据
webview 控制脚本
进入webview
通过am start进入webview
am start -a android.intent.action.VIEW -d urixxxx
滑动操作
因为页面上没有支持 UiScrollable 元素,所以没法使用如下方式:
<code class="hljs java has-numbering"> UiScrollable scrollable = <span class="hljs-keyword">new</span> UiScrollable(<span class="hljs-keyword">new</span> UiSelector().scrollable(<span class="hljs-keyword">true</span>)); <span class="hljs-keyword">if</span> (scrollable.exists()) { <span class="hljs-keyword">boolean</span> isScrolled = scrollable.scrollForward(maxSteps); }</code><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li></ul>
采用土办法,但是更有效的:
<code class="hljs cs has-numbering"> ScreenWidth = mDevice.getDisplayWidth(); ScreenHeight = mDevice.getDisplayHeight(); <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">swipeUp</span>() { <span class="hljs-keyword">int</span> startX = ScreenWidth/<span class="hljs-number">2</span>; <span class="hljs-keyword">int</span> endX = startX; <span class="hljs-keyword">int</span> startY = ScreenHeight/<span class="hljs-number">2</span>; <span class="hljs-keyword">int</span> endY = ScreenHeight/<span class="hljs-number">4</span>; mDevice.swipe(startX, startY, endX, endY, STEP_NUM); }</code><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li></ul>
判断到达顶部和底部
因为取得不到webview的元素,所以采用了一个笨办法,截屏。在滑动操作前后保存截屏数据,当2次的内容相同,则认为滑动到头了。
但是遇到一个问题,webview页面填的内容很多,滑动过程会出现卡顿。当在卡顿时滑动是不起作用的,因此前后2次截屏内容相同,都是卡住的页面,会导致判断错误。
为了解决这个问题,最初采用了延长每次操作后的等待时间来解决,但是这样太浪费时间…
<code class="hljs cs has-numbering"> <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">scrollDown</span>() { log(<span class="hljs-string">"下拉"</span>); <span class="hljs-keyword">while</span>(<span class="hljs-keyword">true</span>){ swipeUp(); sleep(<span class="hljs-number">5000</span>); <span class="hljs-keyword">if</span>(isSame()) <span class="hljs-keyword">break</span>; } }</code><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li></ul>
后来优化采用了判断3次是否相同来解决,效果不错
<code class="hljs scss has-numbering"> public void <span class="hljs-function">scrollDown()</span> { <span class="hljs-function">log(<span class="hljs-string">"下拉"</span>)</span>; <span class="hljs-function">while(true)</span>{ <span class="hljs-function">swipeUp()</span>; <span class="hljs-function">sleep(<span class="hljs-number">1000</span>)</span>; <span class="hljs-function">if(<span class="hljs-function">isSame()</span>)</span>{ <span class="hljs-comment">// 进行截屏,判断两次截屏是否相同,</span> <span class="hljs-function">sleep(<span class="hljs-number">1500</span>)</span>; <span class="hljs-comment">// 如果相同,做滑动操作,然后重新判断</span> <span class="hljs-function">swipeUp()</span>; <span class="hljs-comment">// 重复3次</span> <span class="hljs-function">sleep(<span class="hljs-number">1500</span>)</span>; <span class="hljs-comment">// 如果3次判断都是相同,则不是卡顿</span> <span class="hljs-function">if(<span class="hljs-function">isSame()</span>)</span>{ <span class="hljs-comment">// 经验值,卡顿达不到这么长时间</span> <span class="hljs-function">swipeUp()</span>; <span class="hljs-function">sleep(<span class="hljs-number">1500</span>)</span>; <span class="hljs-function">if(<span class="hljs-function">isSame()</span>)</span>{ break; } } } } }</code><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li></ul>
截屏和判断的程序如下:
<code class="hljs java has-numbering"> <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">takeScreenshot</span>(String path){ File pic = <span class="hljs-keyword">new</span> File(path); <span class="hljs-keyword">boolean</span> ret = mDevice.takeScreenshot(pic); } <span class="hljs-keyword">public</span> <span class="hljs-keyword">boolean</span> <span class="hljs-title">isSame</span>(){ String path = <span class="hljs-string">"/data/local/tmp/Screenshot.png"</span>; takeScreenshot(path); <span class="hljs-keyword">if</span>(bmp0!=<span class="hljs-keyword">null</span>) bmp1 = bmp0.copy(Bitmap.Config.ARGB_8888, <span class="hljs-keyword">true</span>);; bmp0 = BitmapFactory.decodeFile(path); bmp0 = bmp0.copy(Bitmap.Config.ARGB_8888, <span class="hljs-keyword">true</span>); <span class="hljs-keyword">if</span>(bmp0!=<span class="hljs-keyword">null</span> && bmp1!= <span class="hljs-keyword">null</span> && bmp0.sameAs(bmp1)) <span class="hljs-keyword">return</span> <span class="hljs-keyword">true</span>; <span class="hljs-keyword">return</span> <span class="hljs-keyword">false</span>; }</code><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li></ul>
点击顶部 banner
还是因为取得不到webview的元素,所以采用了一个笨办法。因为banner 是webview上的第一个元素,所以先判断顶部工具条的高度,然后再加上页面布局元素的间隙的大小,就是banner 的位置。点击这个位置!
<code class="hljs cs has-numbering"> <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">clickBanner</span>() { UiCollection colls = <span class="hljs-keyword">new</span> UiCollection(<span class="hljs-keyword">new</span> UiSelector().className(<span class="hljs-string">"android.widget.LinearLayout"</span>)); <span class="hljs-keyword">try</span> { UiObject topCat = colls.getChildByInstance(<span class="hljs-keyword">new</span> UiSelector().className(<span class="hljs-string">"android.widget.LinearLayout"</span>),<span class="hljs-number">2</span>); Rect rect = topCat.getBounds(); <span class="hljs-comment">//获取顶部工具条的位置</span> mDevice.click(ScreenWidth/<span class="hljs-number">2</span>,rect.bottom + <span class="hljs-number">30</span>); <span class="hljs-comment">//点击下面30像素中间位置</span> } <span class="hljs-keyword">catch</span> (UiObjectNotFoundException e) { e.printStackTrace(); } mDevice.waitForIdle(); }</code><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li></ul>
第一部分 OK了
取得性能数据
有3种方案:
1,猫客内嵌入了性能测试模块,打包时配置MONITOR_OPEN=true,然后让监控开启即可。不方便之处是不能实时显示成图表~
2,请参见http://blog.csdn.net/kittyboy0001/article/details/47317855
3, 安装易测客户端 http://easytest.taobao.com
这里只对第一种方案做说明,剩下2种方案大家自己看。。。
(当然,我自己更喜欢用第2种方案,因为这个是我自己做的,哈哈哈)
性能监控方案一
在猫客的测试模块中嵌入了一个性能监控的服务,可以监控app运行时的各种参数,在业界有很多独立的app可以做这种动作,嵌入的好处是可以直接使用不用再独立安装。打包时配置MONITOR_OPEN=true 可以让该模块能够生效。
通过如下命令启动服务
<code class="hljs avrasm has-numbering"> am startservice -a <span class="hljs-keyword">com</span><span class="hljs-preprocessor">.xxx</span><span class="hljs-preprocessor">.action</span><span class="hljs-preprocessor">.AUTOTEST</span> --ei frequency <span class="hljs-number">1</span> --es caseId xxxCaseId --es caseName xxxCaseName --es reportIp xx<span class="hljs-preprocessor">.xx</span><span class="hljs-preprocessor">.xx</span><span class="hljs-preprocessor">.xx</span> --ez socketMethod false --ei reportPort <span class="hljs-number">80</span></code><ul class="pre-numbering"><li>1</li><li>2</li></ul>
监控结束时调用如下命令,将测试数据回传到服务器查看
<code class="hljs avrasm has-numbering"> am startservice -a <span class="hljs-keyword">com</span><span class="hljs-preprocessor">.xxx</span><span class="hljs-preprocessor">.action</span><span class="hljs-preprocessor">.SHUTDOWN</span></code><ul class="pre-numbering"><li>1</li></ul>
在我们的测试用例中封装了一个测试类PerformanceTest
来负责这个动作。
有想了解使用的请联系 XXX
done