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

Posted TEST_二 黑

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UI自动化测试框架搭建 —— 编写一个APP自动化相关的知识,希望对你有一定的参考价值。

先来看看效果

测试游记,

test_home_android_text用例执行

视频号

前言

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

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

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

搭建Sonic


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

下载官方提供的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
      #前端页面访问地址,不填默认为http://localhost:3000
      - CLIENT_HOST=http://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):
    """
    移动端打开操作
    http://appium.io/docs/en/writing-running-appium/caps/
    """
    url = "http://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平台上查看运行的效果

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

IOS操作也同理

最后感谢每一个认真阅读我文章的人,下面这个自动化网盘链接也是我费了几天时间整理的非常全面的,对提啥鞥希望也能帮助到有需要的你!

这些资料,对于做【软件测试】想进阶的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴我走过了最艰难的路程,希望也能帮助到你!

凡事要趁早,特别是技术行业,一定要提升技术功底。希望对大家有所帮助…….

以上是关于UI自动化测试框架搭建 —— 编写一个APP自动化的主要内容,如果未能解决你的问题,请参考以下文章

字节7年经验分享,如何从0开始搭建公司自动化测试框架?

基于python语言下的UI自动化测试框架搭建

selenium测试框架快速搭建(ui自动化测试)

iOS安卓app还有web框架ui_framework轻松实现app自动化测试以及web自动化测试

APP的UI自动化测试框架及平台化探索

Android UiAutomator环境搭建及使用