APP自动化测试-Appium编写脚本并执行

App自动化测试(学习笔记二)——编写脚本并执行

  • Appium Inspctor 功能
  • Appium Inspctor 用法
    • 用例录制
  • capability 配置参数
  • app 自动化控制
  • 控件定位
    • xpath 定位
    • UI Automator 原生定位
    • css 定位
    • 特殊控件 toast 识别
  • 强制等待与隐式等待
  • 控件交互

Appium Inspctor 功能

  • UI分析,元素定位
  • 录制用例 **
  • 元素查找测试
  • Attcah 已有的session
  • 云测试

Appium Inspctor 用法

SelectElements:选中元素,查看层级和属性
Swipe By Coordinates:通过坐标点滑动
Tap By Coordinates:通过坐标点点击
Back:返回
Refresh Source & Screenshot:刷新页面
StartRecording:开始录制脚本
Search for element:搜索元素
Copy XML Source to Clipboard:复制 xml 结构
Quit Session & Close Inspector:退出当前 Session

用例录制

  • 获取app的信息
    两种方式获取:
    通过 logcat 日志获取
    mac/Linux: adb logcat ActivityManager:I | grep “cmp"
    windows: adb logcat ActivityManager:I | findstr “cmp” 后启动目标应用
    通过 aapt 获取
    mac/Linux: aapt dump badging wework.apk | grep launchable-activity
    Windows: aapt dump badging wework.apk | findstr launchable-activity
    启动应用命令
    adb shell am start -W -n package-name/activity-name -S
    获取当前页面的名字
    adb shell dumpsys window w | findstr mCurrent

  • 配置待测应用
    platformName:平台,Android/iOS
    deviceName:设备名
    appPackage:应用的包名
    appActivity:应用的页面名 Activity
    noReset: 防止清空缓存信息

  • 开始录制

  • 复制用例

对复制的用例进行简单改造:

  • 添加 capability 信息
  • 初始化webdriver,添加setup和teardown
  • 添加隐式等待和noReset属性增强用例稳定性
  • 添加断言

selenium 版本建议 3.141.0
appium-python-client 版本建议 1.2.0

capability 配置参数

字典caps
功能:配置 Appium 会话,告诉 Appium 服务器需要自动化的平台的应用程序
形式:键值对的集合,键对应设置的名称,值对应设置的值
主要分为三部分:

  1. 公共部分
  2. ios 部分
  3. android 部分

Appium 的客户端和服务端之间进行通信的前提
通过 Desired Capabilities 建立会话

公共部分参数配置

描述
platformName 使用的手机操作系统 iOS,Android,或者 Firefox0S
platformVersion 手机操作系统的版本 例如 7.1, 4.4
deviceName 使用的手机或模拟器类型 iPhone Simulator, iPad Simulator, iPhone Retina 4-inch, Android Emulator, Galaxy S4, 等等…. 在 iOS 上,使用 Instruments的 instruments -s devices 命令可返回一个有效的设备的列表。在 Andorid 上虽然这个参数目前已被忽略,但仍然需要添加上该参数
automationName 使用哪个自动化引擎 android默认使用uiautomator2,ios默认使用XCUTest
noReset 在当前 session 下不会重置应用的状态。默认值为 false true, false
udid 连接的真实设备的唯一设备编号 (Unique device identifier) 例如 1ae203187fc012g

Android 部分特有参数配置

描述
appActivity Activity 的名字是指从你的包中所要启动的 Android acticity。他通常需要再前面添加. (例如 使用 .MainActivity 代替 MainActivity) MainActivity, .Settings
appPackage 运行的 Android 应用的包名 com.example.android.myApp, com.android.settings
appWaitActivity 用于等待启动的 Android Activity 名称 SplashActivity
unicodeKeyboard 启用 Unicode 输入,默认为 false true or false
resetKeyboard true or false
dontStopAppOnReset 首次启动的时候,不停止 app true or false
skipDeviceInitialization 跳过安装,权限设置等操作 true or false

iOS 独有

描述
bundleId 被测应用的 bundle ID 。用于在真实设备中启动测试,也用于使用其他需要 bundle ID 的关键字启动测试。在使用 bundle ID 在真实设备上执行测试时,你可以不提供 app 关键字,但你必须提供 udid 。 例如 io.appium.TestApp
autoAcceptAlerts 当 iOS 的个人信息访问警告 (如 位置、联系人、图片) 出现时,自动选择接受( Accept )。默认值 false true 或者 false
showIOSLog 是否在 appium 日志中显示从设备捕获的任何日志。默认 false true or false

配置优化:添加参数,提高用例的稳定性
{
“noReset”: “true”, // 不清空缓存信息
“dontStopAppOnReset”: “true”, // 首次启动的时候,不停止app
“skipDeviceInitialization”: “true”, // 跳过安装,权限设置等操作
“unicodeKeyBoard”: “true” // 输入中文
}

全部capbility

app 自动化控制

  1. 启动
    启动应用
    方式一:webdriver.remote(“url”,desirecapability)
    self.driver = webdriver.Remote(“http://127.0.0.1:4723/wd/hub”, desire_cap)
    方式二:launch_app() 将应用启动起来
    self.driver.launch_app()#手动关闭应用之后,再启动应用(热启动),会进入app首页
  2. 数据清理
    清空输入框内容clear(),每次输入之前都要进行清空
    self.driver.find_element(AppiumBy.ID,“io.appium.android.apis:id/text”).clear()
  3. 关闭
    退出app回收session,quit()
    self.driver.quit()

控件定位

android基础知识:通过容器的布局属性来管理子控件的位置关系,布局过程就是把界面上的所有的控件,根据他们的间距的大小,摆放到正确的位置。
安卓七大布局:LinearLayout(线性布局)、TableLayout(表格布局)、RelativeLayout(相对布局)、FrameLayout(层布局)、AbsoluteLayout(绝对布局)、GridLayout(网格布局)、ConstraintLayout(约束布局)
安卓四大组件:activity页面,与用户交互的可视化界面、service实现程序后台运行的解决方案、content provider内容提供者,提供程序所需要的数据、broadcast receiver广播接收器,监听外部事件的到来,比如来电
常用控件:TextView文本框控件、EditText可编辑文件控件、Button、ImageButton图片按钮、ToggleButton开关按钮、ImageView 显示图片的控件、CheckBox复选框控件、RadioButton单选框控件
布局是一种可用于放置很多控件的容器,它可以按照一定的规则调整内部控件的位置,从而编写出精美的界面。当然,布局的内部除了放置控件外,也可以放置布局,通过多层布局的嵌套,我们就能够完成一些比较复杂的界面。
————————
ios 基础知识:苹果操作系统,给iPhone,iTouch,iPad使用,目前是ios13.ios去掉了布局的概念,直接用变量之间的相对关系完成位置的计算。系统:MacOSX 开发工具:Xcode 开发语言:ObjectC 安装文件:.ipa文件、.app文件
使用Appium测试ios应用需要使用MacOS操作系统
————————
控件基础知识:
dom:Document Object Model 文件对象模型。
dom应用:最早用于html和js交互。用于表示界面的控件层级,界面的结构化描述,常见的格式为html、xml。核心元素为节点和属性。
xpath:xml路径语言,用于xml中的节点定位。
android应用的层级结构与html不一样,是一个定制的xml
app source 类似于dom,表示app的层级,代表了界面里面所有的控件树的结构。
每个控件都有它的属性(id 、 aid 、 xpath),没有css属性
每个节点node,含各种属性attribute:clickable、text、resource-id、content-desc、bounds
(ios与android的区别:dom属性节点结构类似,名字和属性命名不同)
————————

定位工具

  • ui automator viewer定位工具(ONLY Android)
    安装:Android SDK 自带的界面分析工具,打开 tools/bin 目录下的 uiautomatorviewer 程序
    左上角4个按钮的功能:
    第一个按钮是通过分析给定的文件定位
    第二个按钮是将当前界面截图并分析xml结构(用的最多~)
    第三个按钮与第二个功能类似,可快速加载,但它会对页面内容进行压缩,导致一些控件定位不准确
    第四个按钮是保存当前界面的截图以及xml结构

  • weditor
    要求:python 3.6+ 以上
    安装:weditor 是 python 的第三方库,支持 Android 和 iOS 的界面分析,pip install weditor 进行安装
    运行:安装完成之后,在命令行运行 python -m weditor 即可
    直接启动了一个服务,通过设备的 uuid 连接设备,展示页面结构。

  • appium inspector(***)
    github appium-inspector
    运行 appium inspector、运行 appium server、本地的 adb 已连接设备、Desired Capabilities 参数填写
    点击 Start Session
    注意:在运行appium inspect 的时候需要检查一下weditor在手机上安装的ATX服务是否停止,因为ATX服务会占用uiautomator2的

xpath 定位

XPath语法

UI Automator 原生定位

安卓的工作引擎,速度快,但不支持安卓8以上的版本
官网地址

# ID 定位
driver.find_element_by_android_uiautomator('new UiSelector().resourceId("")')

# 组合定位
driver.find_element_by_android_uiautomator('new UiSelector().resourceId("com.xueqiu.android:id/tab_name").text("我的")')

css 定位

Android: Appium Server 版本 >= 1.19.0
iOS:Appium Server>= 1.21.0
css selector 会转化为 Android/iOS 原生定位的定位策略
Android 转为 Android Uiautomator 定位方式
iOS 转为 class chain 定位方式

driver.find_element(AppiumBy.CSS_SELECTOR,"#com\.xueqiu\.android\:id\/tv_search")
Appium Server 解析前:
{"using":"css selector","value":"#com\\.xueqiu\\.android\\:id\\/tv_search"}
Appium Server 解析后:
{"strategy":"-android uiautomator","selector":"new UiSelector().resourceId(\"com.xueqiu.android:id/tv_search\")",...}

cssselector用法官方说明

# 通过 id
elementById("someResourceID")`
    -> `elementsByCss("#someResourceID")
# 通过 class
elementsByClassName("android.widget.TextView")`
    -> `elementsByCss("android.widget.TextView")
# 通过 accessibility id
elementsByAccessibilityId("Some Content Description")`
    -> `elementsByCss('*[description="Some Content Description"]')
# 通过 xpath
elementsByXpath("//android.widget.TextView[@description='Accessibility']")`
    -> `elementsByCss("android.widget.TextView[description='Accessibility']")

特殊控件 toast 识别

一闪而过的消息提示
toast本身是个系统级别的控件,它归属于系统settings,当一个app发送消息的时候,不是自己造出来的弹框,是发给系统,由系统统一进行弹框,这类的控件不在app内,需要特殊的控件识别办法。
必须使用xpath查找

self.driver.find_element(AppiumBy.XPATH, "//*[@class='android.widget.Toast']")
self.driver.find_element(AppiumBy.XPATH, "//*[contains(@text,'xxxxx')]")
caps["automationName"] = "uiautomator2"

强制等待与隐式等待

避免页面未渲染完成后操作,导致的报错

  1. 强制(直接)等待
    解决方案:在报错的元素操作之前添加等待
    原理:强制等待,线程休眠一定时间
    time.sleep(3)
  2. 隐式等待
    问题:难以确定元素加载的具体等待时间。
    解决方案:针对于寻找元素的这个动作,使用隐式等待添加配置。
    原理:隐式等待是一种全局的等待方式,设置一个等待时间,轮询查找(默认 0.5 秒)元素是否出现,如果没出现就抛出异常
    driver.implicitly_wait(3)
  3. 显式等待
    隐式等待无法解决的问题
    元素可以找到,使用点击等操作,出现报错
    原因:
    页面元素加载是异步加载过程,通常 xml 会先加载完成,相应的元素属性后加载
    元素存在与否是由 xml 决定,元素的交互是由属性决定
    隐式等待只关注元素能不能找到,不关注元素能否点击或者进行其他的交互

示例: WebDriverWait(driver实例, 最长等待时间, 轮询时间).until(结束条件)
原理:在最长等待时间内,轮询,是否满足结束条件

WebDriverWait(driver, 10).until(expected_conditions.element_to_be_clickable((AppiumBy.ID, ‘com.xueqiu.android:id/code’)))
driver.find_element(AppiumBy.ID,“com.xueqiu.android:id/code”).click()

locator = (AppiumBy.XPATH, "//*[@text='SH601601']/../../..//*[@resource-id='com.xueqiu.android:id/current_price']")
WebDriverWait(self.driver,10).until(expected_conditions.visibility_of_element_located(locator))
price = self.driver.find_element(*locator).text
print(f"股票的价格是{price}")
# price_ele = WebDriverWait(self.driver,10).until(lambda x:x.find_element(*locator))
# print(f"股票的价格是{price_ele.text}")

总结

类型 使用方式 原理 适用场景
直接等待 time.sleep(等待时间)) 强制线程等待 调试代码,临时性添加
隐式等待 driver.implicitly_wait(等待时间) 在时间范围内,轮询查找元素 解决找不到元素问题,无法解决交互问题
显式等待 WebDriverWait(driver实例, 最长等待时间, 轮询时间).until(结束条件) 设定特定的等待条件,轮询操作 解决特定条件下的等待问题,比如点击等交互性行为

控件交互

元素的常用方法

点击方法 element.click()
输入操作 element.send_keys(‘appium’)
设置元素的值 element.set_value(‘appium’)
清除操作 element.clear()

是否可见 element.is_displayed() 返回 True/False
是否可用 element.is_enabled() 返回 True/False
是否被选中 element.is_selected() 返回 True/False

获取属性值 get_attribute(name)
get_attribute() 方法能获取的属性,元素的属性几乎都能获取到,属性名称和 uiautomatorviewer 里面的一致

  • resource-id/resourceld 返回 resource-id(API=>18 支持)
  • text 返回 text
  • class 返回 class(API=>18 支持)
  • content-desc/contentDescription 返回 content-desc 属性
  • checkable,checked,clickable,enabled,focusable,focused,{long-clickable,longClickable), package, password,scrollable,selection-start,selection-end,selected,bounds,displayed,contentSize 返回 true or false

获取元素文本element.text
获取元素坐标element.location结果:{‘y’: 19,'x: 498}
获取元素尺寸(高和宽)element.size结果:{‘width’:500,‘height’:22)

你可能感兴趣的:(测试学习笔记,软件测试,自动化,python)