appium、环境配置、并发测试

appium总结,包含入门、进阶、实战

这篇文章面向与实用,拿来即用

基础的事件不进行描述

一、环境搭建

包含Node.js Appium Appium-desktop Appium-doctor Appiun-Python-Client
Python JDK Andriod SDK。配置参考

二、基础操作

Toast元素识别

在app中经常会看到App界面有一些弹窗提示,这些提示元素出现后等待3秒左右就会自动消失,获取不到焦点,无法被点击。

Appium 1.6.3开始支持识别Toast内容,主要是基于UiAutomator2,因此需要在Capablity配置如下参数:
desired_caps['automationName']='uiautomator2'

安装appium-uiautomator2-driver: 安装命令如下:
cnpm install appium-uiautomator2-driver

安装成功后可以在 C:\Users\XXXX\node_modules看到对应的文件:
_appium-uiautomator2-driver@1.12.0@appium-uiautomator2-driver
_appium-uiautomator2-server@1.10.0@appium-uiautomator2-server
代码实现

模拟环境登陆测试,检测到页面出现Toast,进行相关处理。

# coding=utf-8
from find_element.capability import driver
from selenium.webdriver.support.ui import WebDriverWait

driver.find_element_by_id('com.tal.kaoyan:id/login_email_edittext').clear()
driver.find_element_by_id('com.tal.kaoyan:id/login_email_edittext').send_keys('zxss018')

driver.find_element_by_id('com.tal.kaoyan:id/login_password_edittext').send_keys('zxw2018')
driver.find_element_by_id('com.tal.kaoyan:id/login_login_btn').click()

error_message="用户名或密码错误,你还可以尝试4次"
limit_message="验证失败次数过多,请15分钟后再试"

message='//*[@text=\'{}\']'.format(error_message)
# message='//*[@text=\'{}\']'.format(limit_message)

toast_element=WebDriverWait(driver,5).until(lambda x:x.find_element_by_xpath(message))
print(toast_element.text)

滑动操作

在操作app时会出现滑动操作,如刷抖音、浏览朋友圈进行左右或者上下滑动。
滑动示意图如下:
在这里插入图片描述

实践应用
测试场景
安装启动考研帮,手动向水平左滑动首页引导页面。
点击“立即体验”进入登录页面
代码实现
from time import sleep
from find_element.capability import driver

#获取屏幕尺寸
def get_size():
    x=driver.get_window_size()['width']
    y=driver.get_window_size()['height']
    return x,y

#显示屏幕尺寸(width,height)
l=get_size()
print(l)

#向左滑动
def swipeLeft():
    l=get_size()
    x1=int(l[0]*0.9)
    y1=int(l[1]*0.5)
    x2=int(l[0]*0.1)
    driver.swipe(x1,y1,x2,y1,1000)

#向左滑动2次
for i in range(2):
    swipeLeft()
    sleep(0.5)

driver.find_element_by_id('com.tal.kaoyan:id/activity_splash_guidfinish').click()

连续滑动操作

实战——九宫格滑动操作
测试场景

安装启动随手记App 启动App后在密码设置选项中开启手机密码并滑动九宫格设置如下图形密码:
在这里插入图片描述

代码实现
from appium import webdriver
from  time import sleep
from appium.webdriver.common.touch_action import TouchAction
from selenium.webdriver.support.ui import WebDriverWait
from selenium.common.exceptions import NoSuchElementException

desired_caps={}
desired_caps['platformName']='Android'
desired_caps['platformVersion']='5.1.1'
desired_caps['deviceName']='127.0.0.1:62025'

desired_caps['app']=r'C:\Users\Shuqing\Desktop\mymoney.apk'
desired_caps['appPackage']='com.mymoney'
desired_caps['appActivity']='com.mymoney.biz.splash.SplashScreenActivity'

driver = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps)
driver.implicitly_wait(5)
# 获取屏幕尺寸
def get_size():
    x=driver.get_window_size()['width']
    y=driver.get_window_size()['height']
    return x,y

def swipeLeft():
    l=get_size()
    x1=int(l[0]*0.9)
    y1=int(l[1]*0.5)
    x2=int(l[0]*0.1)
    driver.swipe(x1,y1,x2,y1,1000)

def swipeUp():
    l = get_size()
    x1 = int(l[0] * 0.5)
    y1 = int(l[1] * 0.95)
    y2 = int(l[1] * 0.35)
    driver.swipe(x1, y1, x1, y2, 1000)

#等待启动页面元素,然后向左滑动两次,跳过引导页面
WebDriverWait(driver,6).until(lambda x:x.find_element_by_id("com.mymoney:id/next_btn"))
for i in range(2):
    swipeLeft()
    sleep(1)

#点击“开始随手记”按钮
driver.find_element_by_id('com.mymoney:id/begin_btn').click()

#检测是否有活动页面弹窗,如果有就点击关闭
try:
    closBtn=driver.find_element_by_id('com.mymoney:id/close_iv')
except NoSuchElementException:
    pass
else:
    closBtn.click()

#点击更多菜单
driver.find_element_by_id('com.mymoney:id/nav_setting_btn').click()

#等待界面菜单加载出来,然后向上滑动
WebDriverWait(driver,6).until(lambda x:x.find_element_by_id("com.mymoney:id/content_container_ly"))
swipeUp()

#点击高级菜单
driver.find_element_by_android_uiautomator('new UiSelector().text("高级")').click()
#点击密码与手势密码菜单
driver.find_element_by_id('com.mymoney:id/password_protected_briv').click()
#点击手势密码保护
driver.find_element_by_id('com.mymoney:id/lock_pattern_or_not_sriv').click()

#连续滑动两次设置图案密码
for i in range(2):
    TouchAction(driver).press(x=243,y=381).wait(2000)\
        .move_to(x=455,y=390).wait(1000)\
        .move_to(x=643,y=584).wait(1000)\
        .move_to(x=647,y=784).wait(1000)\
        .release().perform()

框架学习unittest

框架功能

在这里插入图片描述在这里插入图片描述

我框架的编写方式,从配置文件入手,操作流程在配置文件中按照顺序进行配置,进行业务流程操作,进行数据配置,进行封装主函数,进行并发运行。

Appium并发综合测试实践

并发测试我自己是这么理解,分配相应的端口,检测端口是否被占用,构建appium进程组,

测试场景

并发启动2个appium服务,再并发启动2台设备测试考研帮App
2个appium服务,端口配置如下:
Appium服务器端口:4723,bp端口为4724
Appium服务器端口:4725,bp端口为4726
2台设备:
127.0.0.1:62025
127.0.0.1:62001
测试app:考研帮Andriod版

场景分析

其实就是将前面所讲的两部分组合起来,先启动appium服务,分配端口设备并发启动app。进行业务操作。

代码执行
from appium_sync.multi_appium import appium_start
from appium_sync.multi_devices import appium_desired
from appium_sync.check_port import *
from time import sleep
import multiprocessing


devices_list=['127.0.0.1:62025','127.0.0.1:62001']

def start_appium_action(host,port):
    '''检测端口是否被占用,如果没有被占用则启动appium服务'''
    if check_port(host,port):
        appium_start(host,port)
        return True
    else:
        print('appium %s start failed!' %port)
        return False

def start_devices_action(udid,port):
    '''先检测appium服务是否启动成功,启动成功则再启动App,否则释放端口'''
    host='127.0.0.1'
    if start_appium_action(host,port):
        appium_desired(udid,port)
    else:
        release_port(port)

def appium_start_sync():
    '''并发启动appium服务'''
    print('====appium_start_sync=====')

    #构建appium进程组
    appium_process=[]

    #加载appium进程

    for i in range(len(devices_list)):
        host='127.0.0.1'
        port = 4723 + 2 * i

        appium=multiprocessing.Process(target=start_appium_action,args=(host,port))
        appium_process.append(appium)

    # 启动appium服务
    for appium in appium_process:
        appium.start()
    for appium in appium_process:
        appium.join()

    sleep(5)

def devices_start_sync():
    '''并发启动设备'''
    print('===devices_start_sync===')

    #定义desired进程组
    desired_process = []

    #加载desired进程
    for i in range(len(devices_list)):
        port = 4723 + 2 * i
        desired = multiprocessing.Process(target=start_devices_action, args=(devices_list[i], port))
        desired_process.append(desired)

    #并发启动App
    for desired in desired_process:
        desired.start()
    for desired in desired_process:
        desired.join()

if __name__ == '__main__':
    appium_start_sync()
    devices_start_sync()

并发用例执行

测试场景

在上面的基础上,并发启动设备执行点击操作。

代码实现

from selenium.common.exceptions import NoSuchElementException

class KybTest(object):
    def __init__(self,driver):
        self.driver=driver

    def check_cancelBtn(self):
        print('check cancelBtn')

        try:
            cancelBtn = self.driver.find_element_by_id('android:id/button2')
        except NoSuchElementException:
            print('no cancelBtn')
        else:
            cancelBtn.click()

    def check_skipBtn(self):
        print('check skipBtn')

        try:
            skipBtn = self.driver.find_element_by_id('com.tal.kaoyan:id/tv_skip')
        except NoSuchElementException:
            print('no skipBtn')
        else:
            skipBtn.click()

    def skip_update_guide(self):
        self.check_cancelBtn()
        self.check_skipBtn()

将执行的用例集成到 multi_devices.py


from appium import webdriver
import yaml
from  time import  ctime
from appium_sync.kyb_test import KybTest

# 读取yaml文件配置
with open('desired_caps.yaml','r') as file:
    data=yaml.load(file)

devices_list=['127.0.0.1:62001','127.0.0.1:62025']

def appium_desired(udid,port):
    desired_caps={}
    desired_caps['platformName']=data['platformName']
    desired_caps['platformVersion']=data['platformVersion']
    desired_caps['deviceName']=data['deviceName']
    desired_caps['udid']=udid

    desired_caps['app']=data['app']
    desired_caps['appPackage']=data['appPackage']
    desired_caps['appActivity']=data['appActivity']
    desired_caps['noReset']=data['noReset']

    print('appium port:%s start run %s at %s' %(port,udid,ctime()))
    driver=webdriver.Remote('http://'+str(data['ip'])+':'+str(port)+'/wd/hub',desired_caps)
    driver.implicitly_wait(5)

    k=KybTest(driver)
    k.skip_update_guide()
    return driver

if __name__ == '__main__':
    appium_desired(devices_list[0],4723)
    appium_desired(devices_list[1],4725)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Yuno Wang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值