十六、App自动化测试实战(一)

1、APP测试的时代背景

我们面临的问题

  • 按月发布->按周发布->按小时发布
  • 多端发布:Android、iOS、微信小程序、h5
  • 多环境发布:联调环境、测试环境、预发布环境、线上环境
  • 多机型发布:众多设备型号、众多系统版本
  • 多版本共存:用户群体中存在多个不同的版本
  • 历史回归测试任务:成百上千条业务用例如何回归
  • 总结:加班+背锅

2、Appium介绍

  • 推荐Appium
    • 跨语言:Java、Python、nodejs等
    • 跨平台
      • Andoid、iOS
      • Windows、Mac
    • 底层多引擎可切换
    • 生态丰富,社区强大

Appium框架结构

  • node.js:appium的运行环境
  • appium desktop:集成了node.js和appium
  • appium server:包含各种工作引擎,根据平台进行切换。是第一个收集日志的位置。
image.png

Appium引擎列表

  • Android
    • espresso
    • selendroid
    • uiautomator
    • uiautomator2[推荐]
  • iOS
    • uiautomation
    • xcuitest [推荐]
  • mac
  • windows

3、Appium环境安装

  • Appium环境参照前面文章
  • sdk 环境:

安装JDK

  • 需要安装1.8版本的JDK,Linux系统通过apt/yum安装openjdk即可,Mac可以通过brew安装,win10的话,可以从学院提供的百度网盘中下载小于200版本的JDK1.8,因为达到200版本在WIn10安装的时候会有闪退的问题

  • 安装过程全程默认即可,不需要更改

  • 安装完毕后需要配置环境变量:首先是JAVA_HOME,是一个独立的环境变量


    clipboard
  • 还有path环境变量中需要配置几项:

%JAVA_HOME%
%JAVA_HOME%\bin
%JAVA_HOME%\jre\bin

安装Android Studio

初始化Android环境、安装SDK

  • 安装Android Studio之后初次启动的时候会需要进行环境的初始化,安装的时候使用标准安装即可。现在国内可以正常访问dl.google.com这个域名了,所以不用配置特殊手段也可以正常安装SDK等内容

SDK默认需要安装的部分

  • 在AndroidStudio欢迎界面打开SDKmanager,在SDK Tools目录下按照如下选择进行安装,注意其中的Build-Tools部分参考最下方的GIF

    Snipaste_2020-08-24_14-10-35

配置环境变量

Windows
  • 在系统变量中新建一个变量,名字为ANDROID_HOME,值为电脑SDK的根目录,一般默认安装的路径为C:\Users\用户名\AppData\Local\Android\Sdk(用户名为你电脑登录用户的用户名),可以去自己的文件夹下查看具体路径,不要写错
  • 修改系统变量中的path变量,添加四条内容,因为可能会有其他软件也带有adb执行文件,未免出现问题,尽量将这四项配置到较靠前的位置
%ANDROID_HOME%\emulator
%ANDROID_HOME%\tools
%ANDROID_HOME%\tools\bin
%ANDROID_HOME%\platform-tools
Linux/Mac
  • 在环境变量中配置ANDROID_HOME变量,值为SDK的根目录,之后将四个文件夹配置到path变量中,并使用source命令或者重启让配置生效
$ANDROID_HOME/emulator
$ANDROID_HOME/platform-tools
$ANDROID_HOME/tools
$ANDROID_HOME/tools/bin

确认配置是否生效

  • 在命令行执行adb version,确认没有报错,提示的adb位置是之前所安装的sdk目录下
  • 在命令行执行emulator -version,确认没有报错,并且显示了Android emulator version信息

修改build-tools版本

  • 由于默认会安装最新版本的bulid-tools,但是30版本开始build-tools配合jdk1.8会报错,所以需要手动降级到29版本,具体降级方法见下图


    t1.gif

注意

  • Appium建议1.5
  • Java 1.8
  • SDK build-tools/下对应的版本,需要使用<=29的版本

4、Android自动化前提依赖

  • Appium Desktop:入门学习工具
  • 设备:模拟器或真机
    • 网易mumu、夜神、雷电、逍遥
    • Android Studio自带emulator[推荐]
    • Genymotion(Windows上不建议)
    • 真机:
      • 安装驱动(手机助手、豌豆荚等)
      • 开发者选项-开启调试模式
  • Android SDK
  • 连接mumu模拟器
    • 【win版】
      • adb connect 127.0.0.1:7555
      • adb shell
    • 【mac版】
      • adb kill-server && adb server && adb shell
  • 下载app使用应用宝等平台
  • 命令行安装:adb install path/*.apk
  • 命令行卸载:adb uninstall 包名
  • 在python中安装依赖包:pip install appium-python-client

获取App信息

  • app入口,两种方式获取
    • 1、通过logcat日志获取
      • mac/ Linux: adb logcat | grep -i ActivityManager
      • windows: adb logcat | findstr -i ActivityManager
        image.png
      • 获取当前页的activity:adb shell dumpsys window | grep mCurrentFocus,所以最好使用上面的方法获取app的启动页
    • 2、通过aapt获取
      • aapt dump badging wework.apk | grep launchable-activity
  • 启动应用
    adb shell am start -W -n <package-name>/<activity-name> -S

5、appium建立连接的python脚本

from appium import webdriver

caps = {}
caps ["platformName"] = "Android"
caps ["deviceName"] = "insane"
caps ["appPackage"] = "com.tencent.wework"
caps ["appActivity"] = ".launch.LaunchSplashActivity"
caps ["noReset"] = "True"

driver = webdriver.Remote("http://localhost:4723/wd/hub",caps)
  • driver = webdriver.Remote("http://localhost:4723/wd/hub",caps)是建立客户端与服务端连接的重要代码

6、元素定位

  • 测试步骤三要素:
    • 定位、交互、断言
  • 定位
    • Id定位(优先级最高)
    • XPath定位(速度慢,定位灵活)
    • Accessibility ID定位(content-desc)
    • Uiautomator定位(速度快,语法复杂)

XPath定位

  • 绝对定位:不推荐
  • 相对定位:
    • //*
    • //*[contains(@resource-id, 'login')](重点)//*[@text=‘登录](重点)
    • //*'contains(@resource-id, 'login') and contains(@text, '登录')](重点)
    • //*[contains(@text,'登录')or contains(@class, 'EditText')](了解)
    • //*ends-with(@text,号)] | //*[starts-with(@text,姓名')] 两个定位的集合列表(了解)
    • //*(@clickable="true”] // android.widget.TextView[string-length(@text)>0 and string-length(@text)<20](了解)
    • //*[contains(@text,"看点')/ancestor::*//*[contains(@class, 'EditText')](轴)(了解)

原生定位

Toast定位

  • appium使用uiautomator底层的机制来分析抓取toast,并且把toast放到控件树里面,但本身并不属于控件。
  • automationName: uiautomator2
  • getPageSource是无法找到的
  • 必须使用xpath查找
    • //*[@class='android.widget. Toast']
    • //*[contains(@text, "xxxxx")]

7、实战代码

#!/usr/bin/python3
# -*- coding: utf-8 -*-
from time import sleep
from appium import webdriver
from appium.webdriver.common.mobileby import MobileBy
  
class TestWX:
    def setup(self):
        caps = {}
        caps ["platformName"] = "Android"
        caps ["deviceName"] = "insane"
        caps ["appPackage"] = "com.tencent.wework"
        caps ["appActivity"] = ".launch.LaunchSplashActivity"
        caps ["noReset"] = "True"

        self.driver = webdriver.Remote("http://localhost:4723/wd/hub",caps)
        self.driver.implicitly_wait(5)

    def teardown(self):
        self.driver.quit()

    def test_contact(self):
        name = "insane"
        gender = '男'
        phone = '12312312312'
        # 点击【通讯录】
        self.driver.find_element(MobileBy.XPATH, "//*[@text='通讯录']").click()
        # 滚动查找【添加成员】
        self.driver.find_element(MobileBy.ANDROID_UIAUTOMATOR,
                                 'new UiScrollable(new UiSelector()'
                                 '.scrollable(true).instance(0))'
                                 '.scrollIntoView(new UiSelector()'
                                 '.text("添加成员").instance(0));')
        # 点击【手动输入添加】
        self.driver.find_element(MobileBy.XPATH, "//*[@text='手动输入添加']").click()
        # 输入姓名
        self.driver.find_element(MobileBy.XPATH, "//*[contains(@text,'姓名')]/../*[text='必填']").send_keys(name)
        # 选择性别
        self.driver.find_element(MobileBy.XPATH, "//*[@text='性别']/..//*[@text='男']").click()
        if gender == '男':
            self.driver.find_element(MobileBy.XPATH, "//*[@text='男']").click()
        elif gender == '女':
            self.driver.find_element(MobileBy.XPATH, "//*[@text='女']").click()

        # 输入手机号
        self.driver.find_element(MobileBy.XPATH, "//*[@text='手机号']").send_keys(phone)
        self.driver.find_element(MobileBy.XPATH, "//*[@text='保存']").click()
        result = self.driver.find_element(MobileBy.XPATH, "//*[@class='android.widget.Toast']").text
        assert result == "添加成功"
        # sleep(2)
        # print(self.driver.page_source)
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。
禁止转载,如需转载请通过简信或评论联系作者。

推荐阅读更多精彩内容