• Day36 移动端自动化


    系列文章目录

    Day01 软件测试基础总结

    Day02 测试用例知识点总结(上)

    Day03 测试用例知识点总结(下)

    Day04 禅道-从安装到卸载

    Day05 MySql的基础使用

    Day06 MySql知识点总结

    Day07 MySql知识点再总结与多表查询

    Day08 redis的基础知识

    Day08 VMware的安装、Linux系统安装和Linux基础命令

    Day09 Linux常用命令总结

    Day10 Linux环境部署和项目构建

    Day11 shell脚本基础知识

    Day12 接口和协议

    Day13 Postman的使用

    Day13 Windows环境下的JDK安装与Tomcat的启动

    Day14 jenkins部署

    Day15 jenkins的简单使用

    Day16 charles的基本使用

    Day17 考试

    Day18 考试

    Day19 Fiddler的简单使用

    Day20 Python基础

    Day21 python 语句基础

    Day22 Python数据类型(上)

    Day23 Python数据类型(下)

    Day24 Python函数

    Day25 Python的文件操作和异常处理

    Day26 Python面向对象

    Day27 Python的部分算法

    Day28 单元测试 unittest

    Day29 单元测试 pytest

    Day30 接口测试requests

    Day31 Web端自动化基础

    Day32 Web自动化进阶

    Day33 PO模型

    Day34 移动端测试(上)

    Day35 移动端测试(下)

    Day36 移动端自动化(上)


    目录

    系列文章目录

    前言

    一、Appium环境搭建

    二、Applium Desktop连接

    三、Applium的基本操作

    四、使用python实现自动化

    五、app端断言 

    总结


    前言

            目前主流的移动端自动化工具有Robotium,Macaca和Appium。Applium支持语言更多,并且支持Android与IOS系统和跨应用。


    一、Appium环境搭建

    1. 安装Node.js (node -v 验证)
    2. 安装JDK,及配置环境变量
    3. 安装SDK,及配置环境变量
    4. 安装Appium桌面版本

    二、Applium Desktop连接

    使用夜神模拟器 

    原本使用蓝叠,一直提示服务器错误,改换为夜神

     

     下面的所需功能中,至少需要deviceName,platformName,appPackage,appActivity这四个值

    desired_caps常用参数:
        platformName                 平台的名称:iOS, Android, or FirefoxOS
        platformVersion              设备系统版本号
        deviceName                   设备号OS:instruments -s devices,Android: adb devices
        app                                  安装文件路径:/abs/path/to/my.apk or http://myapp.com/app
        appActivity                      启动的Activity
        appPackage                    启动的包
        unicodeKeyboard            unicode设置(允许中文输入)
        resetKeyboard                键盘设置(允许中文输入)

    关于appPackage与appActivity的值如何获得,可以使用adb中的查询当前应用程序的包名和启动项命令 ,注意需要打开程序,再执行以下其中任意一条代码,就能拿到想要的两个值:

    1. adb shell dumpsys window w |findstr \/ |findstr name=
    2. adb shell dumpsys window | findstr mCurrentFocus

     启动会话成功后

    三、Applium的基本操作

     录制:

    录制注意左边只是选择元素,右边执行相应操作

     从一个坐标位置滑动到另一个坐标位置,只能是两个点之间的滑动
      方法:swipe(start_x, start_y, end_x, end_y, duration=None)
      参数:
          1.start_x:起点X轴坐标
          2.start_y:起点Y轴坐标
          3.end_x:  终点X轴坐标
          4.end_y,: 终点Y轴坐标
          5.duration: 滑动这个操作一共持续的时间长度,单位:ms
      业务场景:
          1.进入设置
          2.从坐标(148,659)滑动到坐标(148,248)
      代码实现:
          # 滑动没有持续时间
          driver.swipe(188,659,148,248)
          # 滑动持续5秒的时间
          driver.swipe(188,659,148,248,5000)

    scroll滑动事件

    从一个元素滑动到另一个元素,直到页面自动停止
      方法:scroll(origin_el, destination_el)
      参数:
          1.origin_el:滑动开始的元素
          2.destination_el:滑动结束的元素
      业务场景:
          1.进入设置页
          2.模拟手指从存储菜单位置 到 WLAN菜单位置的上滑操作
      代码实现:
          # 定位到存储菜单栏
          el1 = driver.find_element_by_xpath("//*[contains(@text,'存储')]")
          # 定位到WLAN菜单栏
          el2 = driver.find_element_by_xpath("//*[contains(@text,'WLAN')]")
          # 执行滑动操作
          driver.scroll(el1,el2)

    drag拖拽事件
    从一个元素滑动到另一个元素,第二个元素替代第一个元素原本屏幕上的位置
      方法:drag_and_drop(origin_el, destination_el)
      参数:
          1.origin_el:滑动开始的元素
          2.destination_el:滑动结束的元素
      业务场景:
          1.进入设置页
          2.模拟手指将存储菜单 滑动到 WLAN菜单栏位置
      代码实现:
          # 定位到存储菜单栏
          el1 = driver.find_element_by_xpath("//*[contains(@text,'存储')]")
          # 定位到WLAN菜单栏
          el2 = driver.find_element_by_xpath("//*[contains(@text,'WLAN')]")
          # 执行滑动操作
          driver.drag_and_drop(el1,el2)

    应用置于后台事件
      APP放置后台,模拟热启动
      方法:background_app(seconds)
      参数:
          1.seconds:停留在后台的时间,单位:秒
      业务场景:
          1.进入设置页
          2.将APP置于后台5s
      代码实现:
          driver.background_app(5)
      效果:
          app置于后台5s后,再次展示当前页面

    手指轻敲操作

      模拟手指轻敲一下屏幕操作
      方法:tap(element=None, x=None, y=None)
      方法:perform() # 发送命令到服务器执行操作
      参数:
          1.element:被定位到的元素
          2.x:相对于元素左上角的坐标,通常会使用元素的X轴坐标
          3.y:通常会使用元素的Y轴坐标
      业务场景:
          1.进入设置
          2.点击WLAN选项
      代码实现:
          # 通过元素定位方式敲击屏幕
          el = driver.find_element_by_xpath("//*[contains(@text,'WLAN')]")
          TouchAction(driver).tap(el).perform()

          # 通过坐标方式敲击屏幕,WLAN坐标:x=155,y=250
          # TouchAction(driver).tap(x=155,y=250).perform()

    手指按操作

      模拟手指按下屏幕,按就要对应着离开.
      方法:press(el=None, x=None, y=None)
      方法:release() # 结束动作,手指离开屏幕
      参数:
          1.element:被定位到的元素
          2.x:通常会使用元素的X轴坐标
          3.y:通常会使用元素的Y轴坐标
      业务场景:
          1.进入设置
          2.点击WLAN选项
      代码实现:
          # 通过元素定位方式按下屏幕
          el = driver.find_element_by_xpath("//*[contains(@text,'WLAN')]")
          TouchAction(driver).press(el).release().perform()

          # 通过坐标方式按下屏幕,WLAN坐标:x=155,y=250
          # TouchAction(driver).press(x=155,y=250).release().perform()

    等待操作

      方法:wait(ms=0)
      参数:
          ms:暂停的毫秒数
      业务场景:
          1.进入设置
          2.点击WLAN选项
          3.长按WiredSSID选项5秒
      代码实现:
          # 点击WLAN
          driver.find_element_by_xpath("//*[contains(@text,'WLAN')]").click()
          # 定位到WiredSSID
          el =driver.find_element_by_id("android:id/title")
          # 通过元素定位方式长按元素
          TouchAction(driver).press(el).wait(5000).perform()

          # 通过坐标方式模拟长按元素
          # 添加等待(有长按)/不添加等待(无长按效果)
          # TouchAction(driver).press(x=770,y=667).wait(5000).release().perform()

    手指长按操作

      模拟手机按下屏幕一段时间,按就要对应着离开.
      方法:long_press(el=None, x=None, y=None, duration=1000)
      参数:
          1.element:被定位到的元素
          2.x:通常会使用元素的X轴坐标
          3.y:通常会使用元素的Y轴坐标
          4.duration:持续时间,默认为1000ms
      业务场景:
          1.进入设置
          2.点击WLAN选项
          3.长按WiredSSID选项5秒
      代码实现:
          # 点击WLAN
          driver.find_element_by_xpath("//*[contains(@text,'WLAN')]").click()
          # 定位到WiredSSID
          el =driver.find_element_by_id("android:id/title")
          # 通过元素定位方式长按元素
          TouchAction(driver).long_press(el,duration=5000).release().perform()

          # 通过坐标方式长按元素,WiredSSID坐标:x=770,y=667
          # 添加等待(有长按)/不添加等待(无长按效果)
          # TouchAction(driver).long_press(x=770,y=667).perform()

    手指移动操作
      模拟手机的滑动操作
      方法:move_to(el=None, x=None, y=None)
      参数:
          1.el:定位的元素
          2.x:相对于前一个元素的X轴偏移量
          3.y:相对于前一个元素的Y轴偏移量
      业务场景1:
          1.进入设置
          2.向上滑动屏幕
        代码实现:
            # 定位到存储
            el = driver.find_element_by_xpath("//*[contains(@text,'存储')]")
            # 定位到更多
            el1 = driver.find_element_by_xpath("//*[contains(@text,'更多')]")
            # 元素方式滑动
            TouchAction(driver).press(el).move_to(el1).release().perform()
            # 坐标的方式滑动
            # TouchAction(driver).press(x=240,y=600).wait(100).move_to(x=240,y=100).release().perform()
            # 注意press连接一个move_to实际调用的是swip方法,可在log中查询,不要给相对坐标。
        业务场景2:
            1.进入设置
            2.向上滑动屏幕到可见"安全"选项
            3.进入到安全
            4.点击屏幕锁定方式
            5.点击图案
            6.绘制图案
        代码实现:
            # 定位到WLAN
            el1 = driver.find_element_by_xpath("//*[contains(@text,'WLAN')]")
            # 定位到存储
            el2 = driver.find_element_by_xpath("//*[contains(@text,'存储')]")
            # 存储上滑到WLAN
            driver.drag_and_drop(el2,el1)
            # 定位到用户
            el3 = driver.find_element_by_xpath("//*[contains(@text,'用户')]")
            # 注意 这次使用drag_and_drop方法,传入的"存储定位"仍使用其原始在屏幕上的位置,所以是由存储滑动到用户才可以上滑,否则需要重新"定位存储"
            # 存储上滑倒用户位置
            driver.drag_and_drop(el2,el3)
            # 点击安全按钮
            driver.find_element_by_xpath("//*[contains(@text,'安全')]").click()
            # 点击屏幕锁定方式按钮
            driver.find_element_by_xpath("//*[contains(@text,'屏幕锁定')]").click()
            # 点击图案按钮
            driver.find_element_by_xpath("//*[contains(@text,'图案')]").click()
            # 绘制图案四个坐标 1:(244,967) 2:(723,967) 3:(723,1442) 4:(244,1916)
            TouchAction(driver).press(x=244,y=967).wait(100).move_to(x=479,y=0).wait(100)
                .move_to(x=0,y=475).wait(100).move_to(x=-479,y=474).release().perform()

    获取手机时间
      方法:device_time
      代码实现:
          # 获取当前手机的时间
          print(driver.device_time)
      执行结果:
          Wed Dec 27 08:52:45 EST 2017

    获取手机的宽高
      获取手机的宽高,可以根据宽高做一些坐标的操作
      方法:get_window_size()
      代码实现:
          print(driver.get_window_size())
      执行结果:
          {'height': 800, 'width': 480}

    发送键到设备
      模拟系统键值的操作,比如操作honme键,音量键,返回键等。
      方法:keyevent(keycode, metastate=None):
      参数:
          keycode:发送给设备的关键代码
          metastate:关于被发送的关键代码的元信息,一般为默认值
      业务场景:
          1.打开设置
          2.按多次音量增加键
      代码实现:
          for i in range(3):
              driver.keyevent(24)

    操作手机通知栏
      打开手机的通知栏,可以获取通知栏的相关信息和元素操作
      方法:open_notifications()
      业务场景: 
          1.启动设置
          2.打开通知栏
      代码实现:
          driver.open_notifications()

    取手机当前网络
      获取手机当前连接的网络
      方法:network_connection
      业务场景:
          获取手机当前网络模式
      代码实现:
          print(driver.network_connection)
      执行结果:
          6

    设置手机网络
      更改手机的网络模式,模拟特殊网络情况下的测试用例
      方法:set_network_connection(connectionType)
      参数:
          connectionType:需要被设置成为的网络类型
      业务场景:
          1.启动设置
          2.设置手机网络为飞行模式
      代码实现:
          driver.set_network_connection(1)

    手机截图
      截取手机当前屏幕,保存指定格式图片到设定位置
      方法:get_screenshot_as_file(filename)
      参数:
          filename:指定路径下,指定格式的图片.
      业务场景:
          1.打开设置页面
          2.截图当前页面保存到当前目录,命名为screen.png
      代码实现:
          import os
          driver.get_screenshot_as_file(os.getcwd() + os.sep + './screen.png')
      执行结果:
          当前目录下会生成screen.png文件

    四、使用python实现自动化

    需要导入  Appium-python-Client 包 

    1. from appium import webdriver
    2. from appium.webdriver.common.touch_action import TouchAction
    3. import unittest,time
    4. class App_auto(unittest.TestCase):
    5. def setUp(self) -> None:
    6. # server 启动参数
    7. caps = {}
    8. # 设备信息
    9. caps["deviceName"] = "127.0.0.1:62001 device"
    10. caps["platformName"] = "Android"
    11. # app的信息
    12. caps["appPackage"] = "com.android.settings"
    13. caps["appActivity"] = "com.android.settings.Settings"
    14. # 声明我们的driver对象
    15. self.driver = webdriver.Remote("http://localhost:4723/wd/hub", caps)
    16. #隐式等待
    17. self.driver.implicitly_wait(30)
    18. def test_a(self):
    19. driver=self.driver
    20. e1=driver.find_element_by_xpath('//*[contains(@text,"显示")]')
    21. e2=driver.find_element_by_xpath('//*[contains(@text,"应用")]')
    22. driver.scroll(e2,e1)
    23. driver.find_element_by_xpath('//*[contains(@text,"安全")]').click()
    24. driver.find_element_by_xpath('//*[contains(@text,"屏幕锁定方式")]').click()
    25. driver.find_element_by_xpath('//*[contains(@text,"图案")]').click()
    26. time.sleep(2)
    27. TouchAction(driver).press(x=152,y=523).wait(1000).move_to(x=744,y=523).wait(1000).move_to(x=145,y=1118).wait(1000).move_to(x=744,y=1118).release().perform()
    28. if __name__ == '__main__':
    29. unittest.main()

    五、app端断言 

    断言的使用本身可以参考第二十八天的断言,在app端的断言,可以参考下面这个实例:

    1. # 获取主页内容的文本信息,来与我输入的内容做断言,符合既通过,不符合既用例失败
    2. result = driver.find_element_by_id('me.onehome.app:id/tv_Destination').get_attribute('text')
    3. # 判断 是否相等
    4. unittest.TestCase().assertEqual(result,"北京",msg='用例失败')

     结果为用例失败,因为使用的是等于,预期结果是‘北京’,而实际结果是‘北京市’,如果使用的是包含,用例就能通过


    总结

  • 相关阅读:
    LeetCode---SQL刷题4
    Part2_扩展MATSIM_Subpart4_除个人车外的其他模式_第18章 公交路线图匹配半自动工具
    【面试普通人VS高手系列】innoDB如何解决幻读
    Mac M1--iOS 开发笔记(1)
    Norms and Inner Products
    Mysql数据库 16.SQL语言 数据库事务
    ElasticSearch ( 一 ) 安装启动
    Polygon 巨大 的 NFT 市场发生了什么变化?
    leetcode 739. Daily Temperatures 每日温度(中等)
    RuoYi-Vue-Plus (角色部门-数据权限 @DataPermission使用、自定义数据权限、数据权限拦截 、处理器解读)
  • 原文地址:https://blog.csdn.net/lookout99/article/details/126708728