• 一个 jmx 文件只包含一个接口,通用部分/复用部分可以用 Include Controller ,挺好的办法。以前的想法是直接通过 Threads 来管理 Cases ,看来还不如独立开来分文件更灵活。

  • @jxxgxldl 是的,我们的做法基本是一样的。

  • @jxxgxldl *.jtl 是默认的结果格式,默认也是 CSV 不是 XML,当然这个输出格式还是可以配置成 XML 的,在 nogui 下得到的结果是 jtl,当然你可以自己定义文件的扩展名为 CSV,实质是一样的,然后命令行分析。我在 linux 下测试出来都是几个 G 的 jtl,内容是 CSV 格式,然后命令行直接在服务器上面得到结果再拿到本机整理报告的。

    nogui 启动:($jmeter_jar 就是路径到 ApacheJMeter.jar,$jmx 就是测试脚本,$out_log 就是输出的 jtl 文件,$run_log 就是运行过程中的输出每 30 秒 Summary 的,2 个 IP 地址是远程 runner)

    java -jar $jmeter_jar -n -t $jmx -l $out_log -R 8.8.8.8,8.8.4.4 > $run_log &
    

    jtl 内容(也是可以配置的):

    ......
    1451271754342,1659,HTTP-Resuest,200,OK,Threads 1-65,text,true,272,200,200,1659
    1451271754331,1670,HTTP-Resuest,200,OK,Threads 1-43,text,true,272,200,200,1670
    1451271754331,1675,HTTP-Resuest,200,OK,Threads 1-57,text,true,272,200,200,1675
    1451271754331,1676,HTTP-Resuest,200,OK,Threads 1-22,text,true,272,200,200,1676
    1451271754385,1624,HTTP-Resuest,200,OK,Threads 1-71,text,true,272,200,200,1624
    ......
    
  • 至于测试结果分析生成,你可能需要 JMeterPluginsCMD Command Line Tool

    例如生成图片:

    java -jar CMDRunner.jar --tool Reporter --generate-png test.png --input-jtl results.jtl \
      --plugin-type ResponseTimesOverTime --width 800 --height 600
    

    生成 CSV 统计:

    java -jar CMDRunner.jar --tool Reporter --generate-csv test.csv \
      --input-jtl results.jtl --plugin-type ResponseTimesOverTime
    
  • 是啊,adb shell am force-stop <PACKAGE> 简单直接暴力

  • markdown: 怪我咯。语法插件的锅。

  • grep,awk,sed 都有 exe 版,而且不止这些。你可能需要 Cygwin

  • 对比另外一种测试方案:直接写工程在调用 SDK,并在工程中完成各项测试,我认为使用 RPC 方案可以实现数据分离,并且易于扩展,测试结果输出也可以更加灵活。如果使用 JMeter 来执行,还可方便一些不会编码的人来完成测试。未完待续

  • FAQ:

    1. 为什么选择 XML-RPC 而不是 JSON-RPC A: 我首先是准备使用 JSON-RPC 的,奈何它的 Server 端需要自己实现一个 HTTP Servlet。而且 Python 自带了 xmlrpc 库。
  • @dongdong 什么 demo?如果是 AccessibilityService 的话,源码和 APK 在顶部都有链接可下载。如果是 Appium 在代码的话,我也可以贴上来。估计是你没有去系统设置的辅助设置里面打开?

    #!/usr/bin/env python
    #  -*- coding:utf-8 -*-
    
    
    import os
    from time import sleep
    
    import unittest
    
    from appium import webdriver
    
    
    class MyTests(unittest.TestCase):
    
        def setUp(self):
            conf = {}
            conf['platformName'] = 'Android'
            conf['platformVersion'] = '4.4.4'
            conf['deviceName'] = '<your-device-id>'
            conf['app'] = 'http://www.mrqyoung.tk/apps/HiAPK_2.01.apk'
            #conf['appPackage'] = 'com.mrqyoung.hiapk'
            #conf['appActivity'] = '.HiAPKActivity'
            self.driver = webdriver.Remote('http://localhost:4723/wd/hub', conf)
    
        def tearDown(self):
            self.driver.quit()
    
        def _home(self):
            print('Press HOME')
            self.driver.press_keycode(3)
    
        def _back(self):
            print('Press BACK')
            self.driver.press_keycode(4)
    
        def _is_main(self):
            e = self.driver.find_elements_by_id('android:id/title')
            #print(len(e))
            return len(e) == 4
    
        #@unittest.skip("debug")
        def test_installed(self):
            print('test_installed...')
            e = self.driver.find_element_by_name('Installed')
            #e = self.driver.find_element_by_android_uiautomator('new UiSelector().text("Installed")')
            e.click()  # change to TAB_INSTALLED
            self.driver.find_element_by_name('com.android.contacts').click()  # open Contacts' APP_INFO
            self.driver.find_element_by_id('com.android.settings:id/left_button').click()  # tap FORCE_STOP
            self._back()  # back to MAIN
            self._back()
            assert self._is_main()
    
        #@unittest.skip("debug")
        def test_saved(self):
            print('skip test_saved.')
            pass
    
        def test_remote(self):
            print('test_remote...')
            e = self.driver.find_element_by_name('Remote').click()  # change to TAB_REMOTE
            sleep(5)  # wait for webview loading
            e = self.driver.find_element_by_class_name('android.webkit.WebView')
            print(self.driver.contexts)
            self.driver.switch_to.context(self.driver.contexts[-1])
            e = self.driver.find_element_by_id('footer')
            print(e.text)
            e = self.driver.find_element_by_link_text('DeviceInfo.apk')
            print(e.text)
            e.click()
            self.driver.switch_to.context('NATIVE_APP')
            assert self._is_main()
    
        #@unittest.skip("debug")
        def test_apks(self):
            print('skip test_apks.')
            self.driver.find_element_by_name('Apk files').click()
            pass
    
    
    if __name__ == '__main__':
        unittest.main(verbosity=2)
    
  • @zsx10110 刚刚验证了一下,果然一个uiautomator dump就不工作了。但是手动安装了一次到完成的时候它又复活了。这个方式看来还是不合适,该改标题。

    UiAutomator can't be used along with an AccessibilityService. When you turn on the service the uiAutomator will crash.

    However, as UiAutomator 2.0 is based on instrumentation you will probably be able to access the information you need without the service.

    ref

    不过,我又发现,在uiautomator dump使之不工作之后,锁屏一次再解锁一次,它就活了,所以呢,曲线救国也许能行吧

  • @zsx10110 真是不幸呢!我要再验证一下这个问题。但是,昨天我在 Appium 1.4.8 和 1.4.16 两个版本上面都试过,都可以自动安装成功并且把我的用例跑了一遍。无论如何,在我们这里已经满足要求了因为我们的自动化框架无关与 UiAutomator 是通过 cmd 安装启动应用的。

  • 方案:使用 json-rpc 或 xml-rpc 把 app 上的接口暴露出来,在外部用 HTTP 方式通信,理论支持多种语言自己造轮子,也能用 JMeter 来发请求断言验证。

    Appium 采用的也是 RPC 协议 (Remote Procedure Call Protocol),selenium 的 json-rpc。我不知道大家有什么高效的方法来调试 Appium 代码,我的主意就是直接开一个 JMeter 随时发 HTTP 请求来验证一下我当前的操作是否可行(Chrome 的 POSTMAN 插件也可以)。古时候用 monkeyrunner,命令行方式来一步一步调试还是挺方便的。

    RPC 方式一般是被我们用来测试 SDK (library) 的,Python 自带 xml-rpc 库,Android 端有 Apache 的 java xml-rpc server,剩下的就简单了。待我有空来详写一篇吧。

  • Appium Python API 中文版 By-HZJ at 2015年12月05日

    纸巾你好纸巾再见