先来看看效果

测试游记

test_home_android_text用例执行

视频号

前言

APP自动化测试Web自动化测试的不同之处在于它的环境搭建更复杂,不过环境搭建之后,具体的操作步骤是类似的。都是定位元素+操作元素

之前有一篇使用WEditor开发APP自动化测试脚本可以拿来进行APP自动化的定位工具

这次介绍另一款更强大的工具「Sonic」

搭建Sonic

https://sonic-cloud.gitee.io/#/

由于需要连接的设备不多,这次采用「快速搭建」

下载官方提供的docker-compose.yml文件

官方为了数据的持久化采用了本地的mysql数据库,但这样比较麻烦,所以直接修改一下

加了一下


  1. db:

  2.     image: mysql

  3.     command: --character-set-server=utf8 --collation-server=utf8_general_ci

  4.     volumes:

  5.       - mysql_db:/var/lib/mysql

  6.     restart: always

  7.     environment:

  8.       MYSQL_ROOT_PASSWORD: Sonic!@#123

  9.       MYSQL_DATABASE: sonic

  10.       MYSQL_ROOT_HOST: '%'

  11.     ports:

  12.       - "3307:3306"

  13.     networks:

  14.       - sonic-network

我这边主机的ip为172.28.253.211,把它改成你自己的IP就可以了


  1. version: '3'

  2. services:

  3.   db:

  4.     image: mysql

  5.     command: --character-set-server=utf8 --collation-server=utf8_general_ci

  6.     volumes:

  7.       - mysql_db:/var/lib/mysql

  8.     restart: always

  9.     environment:

  10.       MYSQL_ROOT_PASSWORD: Sonic!@#123

  11.       MYSQL_DATABASE: sonic

  12.       MYSQL_ROOT_HOST: '%'

  13.     ports:

  14.       - "3307:3306"

  15.     networks:

  16.       - sonic-network

  17.   sonic-server-simple:

  18.     image: "sonicorg/sonic-server-simple:v1.3.1-beta"

  19.     depends_on:

  20.       - db

  21.     environment:

  22.       #以下为MySql配置,localhost请替换为自己MySql服务的ipv4地址

  23.       - MYSQL_HOST=172.28.253.211

  24.       - MYSQL_PORT=3307

  25.       - MYSQL_DATABASE=sonic

  26.       - MYSQL_USERNAME=root

  27.       - MYSQL_PASSWORD=Sonic!@#123

  28.       #在服务器部署的话,localhost改为服务器ip,port更改为sonic-server-simple暴露的port(一般不变)

  29.       - SONIC_API_HOST=172.28.253.211

  30.       - SONIC_API_PORT=8094

  31.       - SONIC_NETTY_PORT=8095

  32.       #token加密的key值

  33.       - SECRET_KEY=sonic

  34.       #身份验证token有效天数

  35.       - EXPIRE_DAY=14

  36.       #前端页面访问地址,不填默认为http://localhost:3000

  37.       - CLIENT_HOST=http://172.28.253.211:3000

  38.       #文件保留天数(指测试过程产生的文件,包括图片、录像等等)

  39.       - FILE_KEEP_DAY=60

  40.       #测试结果保留天数

  41.       - RESULT_KEEP_DAY=60

  42.       #以下均为Cron表达式

  43.       #清理文件定时任务

  44.       - FILE_CRON=0 0 12 * * ?

  45.       #清理测试结果定时任务

  46.       - RESULT_CRON=0 0 12 * * ?

  47.       #发送日报定时任务

  48.       - DAY_CRON=0 0 10 * * ?

  49.       #发送周报定时任务

  50.       - WEEK_CRON=0 0 10 ? * Mon

  51.     networks:

  52.       - sonic-network

  53.     volumes:

  54.       - files:/keepFiles/

  55.       - files:/imageFiles/

  56.       - files:/recordFiles/

  57.       - files:/packageFiles/

  58.       - files:/logs/

  59.     ports:

  60.       - "8094:8094"

  61.       - "8095:8095"

  62.   sonic-client-web:

  63.     image: "sonicorg/sonic-client-web:v1.3.1-beta"

  64.     environment:

  65.       #在服务器部署的话,localhost改为服务器ip,port更改为sonic-server-simple暴露的port(一般不变)

  66.       - SONIC_API_HOST=172.28.253.211

  67.       - SONIC_API_PORT=8094

  68.     networks:

  69.       - sonic-network

  70.     ports:

  71.       - "3000:80"

  72. volumes:

  73.   files:

  74.   mysql_db:

  75. networks:

  76.   sonic-network:

  77.     driver: bridge

然后按照官网的说明run起来~

然后在插了手机的电脑上运行一个Agent

编写自动化脚本

选择一台安卓设备进入

点击「控件元素」-「获取控件元素」就可以拿到元素定位信息了

把xpath推荐的语句拿出来就可以了

把它放到代码中


  1. - page:

  2.       pageName: home_android

  3.       desc: 首页_android

  4.       locators:

  5.         - { desc: "挂号文案",type: "xpath",value: '//android.view.ViewGroup[contains(@content-desc,"挂号,全国7800+医院")]', name: "registered_text" }

同理拿到问诊和购药的文案


  1. - { desc: "挂号文案",type: "xpath",value: '//android.view.ViewGroup[contains(@content-desc,"挂号,全国7800+医院")]', name: "registered_text" }

  2. - { desc: "问诊文案",type: "xpath",value: '//android.view.ViewGroup[contains(@content-desc,"问诊,27万医生在线服务")]', name: "inquiry_text" }

  3. - { desc: "购药文案",type: "xpath",value: '//android.view.ViewGroup[contains(@content-desc,"购药,微医自营购药更安心")]', name: "buy_medicine_text" }

获取设备序列号

鼠标移动到右上角就可以看到设备序列号了

编写脚本

打开APP

编写一个fixture夹具来打开APP

后面可以根据需求把sys、udid、app放到jenkinsfile中实现参数化构建


  1. @pytest.fixture(scope='module')

  2. def home_android():

  3.     home = HomePage(file_name="home_android")

  4.     with allure.step(f"打开微医APP"):

  5.         home.open_phone(sys='android', udid="8688dab6", app='wy')

  6.         home.click(home.home_index) # 进入首页Tab

  7.         time.sleep(2)

  8.     yield home

  9.     home.close()

调试的时候修改打开手机对应的url


  1. def open_phone(self, sys='android', udid="8688dab6", app='wys', apk=None):

  2.     """

  3.     移动端打开操作

  4.     http://appium.io/docs/en/writing-running-appium/caps/

  5.     """

  6.     url = "http://172.28.57.33:4723/wd/hub"

  7.     desired_caps = {"udid": udid}

  8.     if sys == 'android':

  9.         desired_caps['platformName'] = "Android"

  10.         if app == 'wys':

  11.             # 打开微医生APP

  12.             desired_caps["appPackage"] = "com.greenline.yihuantong"

  13.             desired_caps["appActivity"] = ".home.WelcomeActivity"

  14.         elif app == 'wy':

  15.             # 打开微医APP

  16.             desired_caps["appPackage"] = "com.greenline.guahao"

  17.             desired_caps["appActivity"] = ".home.WelcomeActivity"

  18.         desired_caps["skipServerInstallation"] = True

  19.         desired_caps["automationName"] = "UiAutomator2"

  20.         desired_caps["noReset"] = True

  21.         desired_caps["newCommandTimeout"] = 3600

  22.     elif sys == 'ios':

  23.         desired_caps['platformName'] = "iOS"

  24.         if app == 'wys':

  25.             # 打开微医生APP

  26.             desired_caps["bundleId"] = "com.minkanginfo.guahao"

  27.         elif app == 'wy':

  28.             # 打开微医APP

  29.             desired_caps["bundleId"] = "com.lvxian.guahao"

  30.         desired_caps["automationName"] = "XCUITest"

  31.     if apk:

  32.         desired_caps1 = copy.deepcopy(desired_caps)

  33.         desired_caps1["appPackage"] = "com.android.settings"

  34.         desired_caps1["appActivity"] = ".Settings"

  35.         driver = app_webdriver.Remote(url, desired_caps1)

  36.         if app == 'wys':

  37.             self.install_apk(driver, "com.greenline.yihuantong", apk)

  38.         elif app == 'wy':

  39.             self.install_apk(driver, "com.greenline.guahao", apk)

  40.         driver.quit()

  41.     print(desired_caps)

  42.     self.driver = app_webdriver.Remote(url, desired_caps)

  43.     self.wait_for(10)

  44.     return self.driver

注意这个函数内部根据实际打开的APP来进行修改或调整

根据需求修改

appPackage

appActivity

使用上面这个url的时候需要在对应的电脑上打开Appium,端口指定为默认端口4723

踩坑

自动化安装包

在给小米手机自动安装APP的时候老是有弹框,可以通过下面方式修改:

设置 -> 授权管理 -> 右上角设置按钮 -> USB安装管理 ->关闭

如果授权管理页面的右上角没有设置按钮

开发者选项中 -> 启动MIUI优化 ->关闭

再返回到授权页面,就可以看到 右上角的设置按钮了

关闭USB安装管理后,通过USB安装就不会有确认弹窗了

反复提示需要安装uiautomator2

使用Appium控制部分安卓手机时,重复提示需要安装uiautomator2

desired_caps["skipServerInstallation"] = True

编写用例主体

用例内容和上次一样,不过这次换成了打开APP


  1. @compose(feature="微医APP", story="首页", title='主入口下方文案校验')

  2. @pytest.mark.parametrize("way", ["registered_text", "inquiry_text", "buy_medicine_text"])

  3. def test_home_android_text(home_android, way):

  4.     """

  5.     按钮下方文案测试

  6.         * 挂号

  7.         * 问诊

  8.         * 购药

  9.     """

  10.     ele = getattr(home_android, way)

  11.     with allure.step(f"查看{ele.desc}"):

  12.         text = home_android.get_attribute(ele, "content-desc")

  13.         if way == 'registered_text':

  14.             assert text == '挂号,全国7800+医院'

  15.         elif way == 'inquiry_text':

  16.             assert text == '问诊,27万医生在线服务'

  17.         elif way == 'buy_medicine_text':

  18.             assert text == '购药,微医自营购药更安心'

使用参数化的方式测试三个地方的文案是否符合要求

运行与查看结果

运行之后,直接在Sonic平台上查看运行的效果

代码见:https://gitee.com/zx660644/uitest/tree/first_android_test

IOS操作也同理

 如果我的博客对你有帮助、如果你喜欢我的博客内容,请 “点赞” “评论” “收藏” 一键三连哦!

 最后: 下方这份完整的软件测试视频教程已经整理上传完成,需要的朋友们可以自行领取【保证100%免费】

Logo

技术共进,成长同行——讯飞AI开发者社区

更多推荐