admin管理员组

文章数量:1794759

UI自动化测试框架搭建 —— 编写一个APP自动化

UI自动化测试框架搭建 —— 编写一个APP自动化

先来看看效果

测试游记,

test_home_android_text用例执行

视频号

前言

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

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

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

搭建Sonic

sonic-cloud.gitee.io/#/

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

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

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

加了一下

db:     image: mysql     command: --character-set-server=utf8 --collation-server=utf8_general_ci     volumes:       - mysql_db:/var/lib/mysql     restart: always     environment:       MYSQL_ROOT_PASSWORD: Sonic!@#123       MYSQL_DATABASE: sonic       MYSQL_ROOT_HOST: '%'     ports:       - "3307:3306"     networks:       - sonic-network

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

version: '3' services:   db:     image: mysql     command: --character-set-server=utf8 --collation-server=utf8_general_ci     volumes:       - mysql_db:/var/lib/mysql     restart: always     environment:       MYSQL_ROOT_PASSWORD: Sonic!@#123       MYSQL_DATABASE: sonic       MYSQL_ROOT_HOST: '%'     ports:       - "3307:3306"     networks:       - sonic-network   sonic-server-simple:     image: "sonicorg/sonic-server-simple:v1.3.1-beta"     depends_on:       - db     environment:       #以下为MySql配置,localhost请替换为自己MySql服务的ipv4地址       - MYSQL_HOST=172.28.253.211       - MYSQL_PORT=3307       - MYSQL_DATABASE=sonic       - MYSQL_USERNAME=root       - MYSQL_PASSWORD=Sonic!@#123       #在服务器部署的话,localhost改为服务器ip,port更改为sonic-server-simple暴露的port(一般不变)       - SONIC_API_HOST=172.28.253.211       - SONIC_API_PORT=8094       - SONIC_NETTY_PORT=8095       #token加密的key值       - SECRET_KEY=sonic       #身份验证token有效天数       - EXPIRE_DAY=14       #前端页面访问地址,不填默认为localhost:3000       - CLIENT_HOST=172.28.253.211:3000       #文件保留天数(指测试过程产生的文件,包括图片、录像等等)       - FILE_KEEP_DAY=60       #测试结果保留天数       - RESULT_KEEP_DAY=60       #以下均为Cron表达式       #清理文件定时任务       - FILE_CRON=0 0 12 * * ?       #清理测试结果定时任务       - RESULT_CRON=0 0 12 * * ?       #发送日报定时任务       - DAY_CRON=0 0 10 * * ?       #发送周报定时任务       - WEEK_CRON=0 0 10 ? * Mon     networks:       - sonic-network     volumes:       - files:/keepFiles/       - files:/imageFiles/       - files:/recordFiles/       - files:/packageFiles/       - files:/logs/     ports:       - "8094:8094"       - "8095:8095"   sonic-client-web:     image: "sonicorg/sonic-client-web:v1.3.1-beta"     environment:       #在服务器部署的话,localhost改为服务器ip,port更改为sonic-server-simple暴露的port(一般不变)       - SONIC_API_HOST=172.28.253.211       - SONIC_API_PORT=8094     networks:       - sonic-network     ports:       - "3000:80" volumes:   files:   mysql_db: networks:   sonic-network:     driver: bridge

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

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

编写自动化脚本

选择一台安卓设备进入

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

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

把它放到代码中

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

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

- { desc: "挂号文案",type: "xpath",value: '//android.view.ViewGroup[contains(@content-desc,"挂号,全国7800+医院")]', name: "registered_text" } - { desc: "问诊文案",type: "xpath",value: '//android.view.ViewGroup[contains(@content-desc,"问诊,27万医生在线服务")]', name: "inqUIry_text" } - { desc: "购药文案",type: "xpath",value: '//android.view.ViewGroup[contains(@content-desc,"购药,微医自营购药更安心")]', name: "buy_medicine_text" } 获取设备序列号

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

编写脚本 打开APP

编写一个fixture夹具来打开APP

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

@pytest.fixture(scope='module') def home_android():     home = HomePage(file_name="home_android")     with allure.step(f"打开微医APP"):         home.open_phone(sys='android', udid="8688dab6", app='wy')         home.click(home.home_index) # 进入首页Tab         time.sleep(2)     yield home     home.close()

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

def open_phone(self, sys='android', udid="8688dab6", app='wys', apk=None):     """     移动端打开操作     appium.io/docs/en/writing-running-appium/caps/     """     url = "172.28.57.33:4723/wd/hub"     desired_caps = {"udid": udid}     if sys == 'android':         desired_caps['platformName'] = "Android"         if app == 'wys':             # 打开微医生APP             desired_caps["appPackage"] = "com.greenline.yihuantong"             desired_caps["appActivity"] = ".home.WelcomeActivity"         elif app == 'wy':             # 打开微医APP             desired_caps["appPackage"] = "com.greenline.guahao"             desired_caps["appActivity"] = ".home.WelcomeActivity"         desired_caps["skipServerInstallation"] = True         desired_caps["automationName"] = "UiAutomator2"         desired_caps["noReset"] = True         desired_caps["newCommandTimeout"] = 3600     elif sys == 'ios':         desired_caps['platformName'] = "iOS"         if app == 'wys':             # 打开微医生APP             desired_caps["bundleId"] = "com.minkanginfo.guahao"         elif app == 'wy':             # 打开微医APP             desired_caps["bundleId"] = "com.lvxian.guahao"         desired_caps["automationName"] = "XCUITest"     if apk:         desired_caps1 = copy.deepcopy(desired_caps)         desired_caps1["appPackage"] = "com.android.settings"         desired_caps1["appActivity"] = ".Settings"         driver = app_webdriver.Remote(url, desired_caps1)         if app == 'wys':             self.install_apk(driver, "com.greenline.yihuantong", apk)         elif app == 'wy':             self.install_apk(driver, "com.greenline.guahao", apk)         driver.quit()     print(desired_caps)     self.driver = app_webdriver.Remote(url, desired_caps)     self.wait_for(10)     return self.driver

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

根据需求修改

appPackage

appActivity

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

踩坑

自动化安装包

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

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

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

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

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

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

反复提示需要安装uiautomator2

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

desired_caps["skipServerInstallation"] = True

编写用例主体

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

@compose(feature="微医APP", story="首页", title='主入口下方文案校验') @pytest.mark.parametrize("way", ["registered_text", "inquiry_text", "buy_medicine_text"]) def test_home_android_text(home_android, way):     """     按钮下方文案测试         * 挂号         * 问诊         * 购药     """     ele = getattr(home_android, way)     with allure.step(f"查看{ele.desc}"):         text = home_android.get_attribute(ele, "content-desc")         if way == 'registered_text':             assert text == '挂号,全国7800+医院'         elif way == 'inquiry_text':             assert text == '问诊,27万医生在线服务'         elif way == 'buy_medicine_text':             assert text == '购药,微医自营购药更安心'

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

运行与查看结果

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

代码见:gitee/zx660644/uitest/tree/first_android_test

IOS操作也同理

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


最后基础知识、Linux必备、Shell、互联网程序原理、Mysql数据库、抓包工具专题、接口测试工具、测试进阶-Python编程、Web自动化测试、APP自动化测试、接口自动化测试、测试高级持续集成、测试架构开发测试框架、性能测试、安全测试等配套学习资源在下方公众号免费获取~

本文标签: 框架测试uiapp