1.获取driver属性

  1. current_package:获取包名
  2. current_activity:获取当前活动页面 ==>url
  3. context:上下文 web窗口切换,H5测试获取上下文  driver.switch_to.context
  4. contexts:所有的上下文 ==>window_handers
  5. current_context:获取现在的上下文  获取当前窗口current_window_hander
  6. page_source:获取源码 XML
  7. capabilities:获取设置的capabilities
  8. device_time:设备时间
  9. location:定位
import time

from appium.webdriver import Remote

# 启动一次请求
caps = {"platformName": "Android",
        "udid": "emulator-5554",
        "appPackage": "com.lemon.lemonban",
        "appActivity": ".activity.WelcomeActivity"
        }
driver = Remote(command_executor='http://127.0.0.1:4723/wd/hub',
                desired_capabilities=caps)
# 设置隐性等待
driver.implicitly_wait(10)
# 获取app当前活动页面名称
print(driver.current_activity)
# 获取源代码XML
driver.page_source
# 获取定位
print(driver.location)
# 获取设置的capabilities
print(driver.capabilities)
driver.quit()

运行结果:

2.获取元素属性

  1. text:获取元素的文本
  2. rect:获取元素的尺寸
import time

from appium.webdriver import Remote

# 启动一次请求
# 1.指明需要连接的服务地址和端口号
# 2.You must include a platformName capability
caps = {"platformName": "Android",
        "udid": "emulator-5554",
        "appPackage": "com.lemon.lemonban",
        "appActivity": ".activity.WelcomeActivity"
        }
driver = Remote(command_executor='http://127.0.0.1:4723/wd/hub',
                desired_capabilities=caps)
# 设置隐性等待
driver.implicitly_wait(10)
el = driver.find_element('xpath', '(//*[@resource-id="com.lemon.lemonban:id/category_description"])[8]')
# 获取元素的文本
print(el.text)
# 获取元素的尺寸
print(el.rect)
time.sleep(3)
driver.quit()

运行结果:

3.用户操作

  1. click() 点击
  2. send_keys() 输入

用法跟selenium中的用法是一样的,但有个注意点:如果想输入中文,必须要设置两个参数

4.触屏操作

  1. tap:相当于全局的click,适合封装在basepage中
  2. move_to
  3. press
  4. long_press
  5. release
  6. wait
  7. flick

5.滑动操作 

  • driver.swipe()

在现在的手机中,滑动操作是常见的操作,如果引导页的滑动,刷新,向上一直滑动加载新内容等

如引导页是一个元素,所以只能通过滑动操作来控制元素

driver.swipe(start_x=700, end_x=10, start_y=500, end_y=10)
这种固定的写法不可取,为什么呢?因为我们现在的手机尺寸有大有小,这样就会造成在这个手机上能执行,在那个手机上不能执行,所以我们要想一种不同尺寸的手机都可以执行的写法,因此我们可以使用比例控制

第一步:我们要得到屏幕的尺寸,使用到get_window_size()方法得到width与height的值,看源码可知返回值是个字典,因此可以取出key的value

print(driver.get_window_size())运行结果:{'width': 900, 'height': 1600}

第二步:使用屏幕的比例来进行滑动,如从右往左滑动,从屏幕宽度的90%滑动到10%的位置,高度不变

driver.swipe(start_x=width * 0.9, end_x=width * 0.1, start_y=height * 0.5, end_y=height * 0.5)

具体代码如下:

import time

from appium.webdriver import Remote

# 启动一次请求
caps = {"platformName": "Android",
        "udid": "emulator-5554",
        "appPackage": "com.xxzb.fenwoo",
        "appActivity": ".activity.addition.SplashActivity",
        "unicodeKeyboard": True,
        "resetKeyboard": True
        }
driver = Remote(command_executor='http://127.0.0.1:4723/wd/hub',
                desired_capabilities=caps)
# 设置隐性等待
driver.implicitly_wait(10)
# 滑动操作
# 1.获取屏幕的宽度和高度
# 2.从右到左滑动
width = driver.get_window_size()['width']
height = driver.get_window_size()['height']
driver.swipe(start_x=width * 0.9, end_x=width * 0.1, start_y=height * 0.5, end_y=height * 0.5)
driver.swipe(start_x=width * 0.9, end_x=width * 0.1, start_y=height * 0.5, end_y=height * 0.5)
driver.swipe(start_x=width * 0.9, end_x=width * 0.1, start_y=height * 0.5, end_y=height * 0.5)
driver.quit()

这种方法有没有觉得太重复了,因此我们可以进行封装,这样就可以调用了,所以我们可以封装到basepage类中

basepage.py代码如下:

class BasePage:
    def __init__(self, driver):
        self.driver = driver

    def width(self):
        """获取app的宽度"""
        return self.driver.get_window_size()['width']

    def height(self):
        """获取app的高度"""
        return self.driver.get_window_size()['height']

    def swipe_left(self):
        """从右往左滑动"""
        self.driver.swipe(start_x=self.width() * 0.9, end_x=self.width() * 0.1,
                          start_y=self.height() * 0.5, end_y=self.height() * 0.5)

    def swipe_right(self):
        """从左往右滑动"""
        self.driver.swipe(start_x=self.width() * 0.1, end_x=self.width() * 0.9,
                          start_y=self.height() * 0.5, end_y=self.height() * 0.5)

    def swipe_up(self):
        """从下往上滑动"""
        self.driver.swipe(start_x=self.width() * 0.5, end_x=self.width() * 0.5,
                          start_y=self.height() * 0.9, end_y=self.height() * 0.1)

    def swipe_down(self):
        """从上往下滑动"""
        self.driver.swipe(start_x=self.width() * 0.5, end_x=self.width() * 0.5,
                          start_y=self.height() * 0.1, end_y=self.height() * 0.9)

调用代码如下:

from basepage import BasePage

from appium.webdriver import Remote

# 启动一次请求
caps = {"platformName": "Android",
        "udid": "emulator-5554",
        "appPackage": "com.xxzb.fenwoo",
        "appActivity": ".activity.addition.SplashActivity",
        "unicodeKeyboard": True,
        "resetKeyboard": True
        }
driver = Remote(command_executor='http://127.0.0.1:4723/wd/hub',
                desired_capabilities=caps)
# 设置隐性等待
driver.implicitly_wait(10)
# 滑动操作
# 直接调用BasePage类中的方法即可
BasePage(driver).swipe_left()
BasePage(driver).swipe_left()
BasePage(driver).swipe_left()
driver.quit()

运行结果是一样的,虽然封装的过程麻烦,但之后再调用就会很方便,而且也方便代码维护

6.start_activity进入页面 

app的路径依赖是很严重的,如果需要测试某个单独的页面,但是进入这个页面有很长的路径,则会严重影响效率,而且路径过长,会让测试程序不稳定

start_activity可以快速进入指定页面,只需要指定activity的名称即可

获取当前页面的名称:

 adb shell -s 设备名称 dumpsys activity | find "mResumedActivity" (如果有多台设备加上-s)

注意:要获取哪个页面名称,一定要打开app的那个页面

代码如下:

driver.start_activity('com.lemon.lemonban', '.activity.LoginActActivity')

在不同的app中都可以使用,直接跳转到设置的页面 

7.按键操作

# 按键操作
# 1.选通过功能查对应的事件数字
# 2.通过press_keycode()方法发送
driver.press_keycode(24)

具体的按键对应的事件数字可参考此网站:https://www.jianshu.com/p/f7ec856ff56f

注意:相机键模拟器是无法进行操作的,只能真机操作

上面的代码可读性太差,时间长了肯定就不记得24代表什么了,因此我们进行封装,增强可读性,封装的代码也可以放到basepage.py中

class MobileKey:
    ENTER = 66
    VOLUME_UP = 24
    VOLUME_DOWN = 25

调用MobileKey中的类属性

driver.press_keycode(MobileKey.VOLUME_UP)

还可以把常用的方法进行二次封装,代码如下:

class MobileKey:
    ENTER = 66
    VOLUME_UP = 24
    VOLUME_DOWN = 25
    BACK = 4


class BasePage:
    def __init__(self, driver):
        self.driver = driver

    def enter(self):
        """回车"""
        self.driver.press_keycode(MobileKey.ENTER)

    def volume_up(self):
        """音量加"""
        self.driver.press_keycode(MobileKey.VOLUME_UP)

    def volume_down(self):
        """音量减"""
        self.driver.press_keycode(MobileKey.VOLUME_DOWN)

    def back(self):
        """返回"""
        self.driver.press_keycode(MobileKey.BACK)

调用BasePage类中的方法即可

BasePage(driver).volume_up()

8.Toast弹框

前提:

登录:Toast是viewer识别不到的,但是我们需要确认文本是否正确

  • appium server 1.6.3以上
  • 代码中必须制定automationName为UiAutomator2                   
  • UiAutomator2只支持安卓版本5.0+
  • jdk1.8 64位以上并配置JAVA_HOME环境变量

因为现在 appium server的版本比较高,默认使用的也是UiAutomator2,所以上面提到的前提不用特意设置

定位表达式: 

  • xpath定位://*[contains(@text,"手机号码格式不正确")]
  • find_element("xpath","//android.widget.Toast")
from appium.webdriver import Remote

# 启动一次请求
caps = {"platformName": "Android",
        "udid": "emulator-5554",
        "appPackage": "com.lemon.lemonban",
        "appActivity": ".activity.WelcomeActivity",
        "unicodeKeyboard": True,
        "resetKeyboard": True,
        "automationName": "UiAutomator2"
        }
driver = Remote(command_executor='http://127.0.0.1:4723/wd/hub',
                desired_capabilities=caps)
# 设置隐性等待
driver.implicitly_wait(10)
# 查找元素输入账号密码,点击登录按钮
driver.start_activity('com.lemon.lemonban', '.activity.LoginActActivity')
driver.find_element('id', 'com.lemon.lemonban:id/et_mobile').send_keys('123')
driver.find_element('id', 'com.lemon.lemonban:id/et_password').send_keys('123')
driver.find_element('id', 'com.lemon.lemonban:id/btn_login').click()
el = driver.find_element('xpath', '//android.widget.Toast')
# 断言
assert el.text == '手机号码格式不正确'
driver.quit()

注意:以上所有的代码最后一定要加上driver.quit(),否则非正常关闭,下次再跑代码就会报错,这是appium的一个bug

9. 混合应用Hybrid App

原生应用是使用系统原生的组件开发的app,需要特定的语言,比如android的java,kotlin,ios的swift,object c

H5技术可以使用web技术开发app,原生和H5的组合就成了混合应用

混合应用不是在app上直接写HTML页面,而是把H5页面放在一个webview控件当中

webview是原生应用的一种控件,还有其他ImageView等,webview能做到和web页面交互的功能

常用的混合应用技术框架:

  • Cordova Apache
  • React Native,RN
  • lonic
  • Flutter,谷歌出的

如何区分是原生页面还是web网页:

方式一:UI上区分:看页面上方有没有进度条与关闭按钮

方式二:利用元素定位区分:原生页面是有很多元素,而且好定位,而web页面整个页面是一个元素,并且class名称是固定的android.webkit.WebView

方式三:下拉页面,背面会出现一个网址(这个不一定有)

方式四:网页定位工具chrome://inspect(这个是判断是不是webview最可靠的工具,但不稳定,速度慢,经常打不开定位元素页面)

chrome://version/查看一些信息

输入chrome://inspect,可以打开DevTools工具,下图是连接上了设备后的显示

当app中打开了一个网页时,刷新DevTools工具,可以查看到关于网页的相关信息,需要注意的是显示的chrome版本是手机端的不是浏览器的版本

点击inspect,就进入了定位元素的页面,其实就是F12的功能

方式五:当方式四不好用的时候,可以下载一个UC-DevTools工具,下载网址:https://dev.ucweb.com/docs/pwa/docs-zh/xy3whu

 

下载安装好,打开界面如下:

 注意:设置中一定要选择本地资源

 点击inspect后,进入元素定位页面,可以看到跟网页的那个显示是一样的

10.其他操作

  • driver.hide_keyboard() 隐藏键盘
  • driver.get_screentshot_as_file() 截屏
  • shake 摇一摇
  • lock 锁屏
  • unlock 解屏

三种等待方法(同selenium用法) 

更多推荐