引言
自动化测试为我们解决了很多繁琐的工作量,但是有时遇到手机兼容性导致无法使用自动化测试进行覆盖的问题。主要难点在于如何使用Appium同时控制多个设备,这次分享将为大家提供同时控制多设备的解决方案。
Appium
工具介绍
Appium是一个开源的自动化测试框架,可用于原生或混合型的移动端APP测试。 该框架支持JAVA,Python,PHP等语言编写的测试脚本。
通信原理
- Client端通过HTTP POST请求方式以Webdriver协议的JSON格式字符串发送command给指定端口,默认端口号4723。
- Appium Server 监听端口,将其转换为Device能够识别的command发送给Device,
- Android端通过Bootstrap监听端口接收Appium Server的指令,通过调用UIAutomator命令实现command操作,将执行的结果返回给Appium server。
安装使用
下载安装:Releases · appium/appium-desktop · GitHub
配置Server Address和Server Port
点击"start Server"按钮,启动Appium服务器,默认监听4723端口
点击“Start Inspector Session”按钮配置Desired Capabilities,点击“Start Session”创建会话
至此,已完成启动Appium服务器以及创建单个设备的session。下面开始讲解如何实现在自动化测试中实现同时控制多设备。
实现思路
1、将每个手机的Desired Capabilities分别保存到文件,文件名以手机型号命名
2、实现接口通过手机型号可查找对应的Desired Capabilities
3、注册命令行选项,输入手机型号即可查找对应手机的Desired Capabilities
4、命令行方式启动appium server
5、多线程调用命令行方式启动脚本
代码演示
配置desired_caps
为每个手机单独创建一个配置文件,包含desired_caps配置信息,注意每个手机需设置不同的systemPort。
HONOR_9X.py
desired_caps = dict()
desired_caps['platformName'] = 'Android'
desired_caps['platformVersion'] = '10'
desired_caps['deviceName'] = 'C7YVB20326000301'
desired_caps['udid'] = 'C7YVB20326000301'
desired_caps['systemPort'] = 8200
desired_caps['automationName'] = 'uiautomator2'
desired_caps['app'] = "D:\\apk_url\\debug.apk"
desired_caps['appPackage'] = 'xxx.xxxx.xxx'
desired_caps['appActivity'] = 'xxx.xx.xxx.system.ui.activity.SplashActivity'
desired_caps['appWaitActivity'] = 'xxx.xx.xxx.system.ui.activity.SplashActivity'
desired_caps['sessionOverride'] = True
desired_caps['unicodeKeyboard'] = True
desired_caps['resetKeyboard'] = True
desired_caps['autoGrantPermissions'] = True
desired_caps['newCommandTimeout'] = 36000
desired_caps['noReset'] = True
config = {
"fileName": "HONOR_9X",
"caps": desired_caps,
"config": "HONOR_9X",
"deviceName": "C7YVB20326000301",
"permission": "And 10"
}
HUAWEI_Mate30_Pro.py
desired_caps = dict()
desired_caps['platformName'] = 'Android'
desired_caps['platformVersion'] = '10'
desired_caps['deviceName'] = 'C7YNW19C04000184'
desired_caps['udid'] = 'C7YNW19C04000184'
desired_caps['systemPort'] = 8201
desired_caps['automationName'] = 'uiautomator2'
desired_caps['app'] = "D:\\apk_url\\debug.apk"
desired_caps['appPackage'] = 'xxx.xxxx.xxx'
desired_caps['appActivity'] = 'xxx.xx.xxx.system.ui.activity.SplashActivity'
desired_caps['appWaitActivity'] = 'xxx.xx.xxx.system.ui.activity.SplashActivity'
desired_caps['sessionOverride'] = True
desired_caps['unicodeKeyboard'] = True
desired_caps['resetKeyboard'] = True
desired_caps['autoGrantPermissions'] = True
desired_caps['newCommandTimeout'] = 36000
desired_caps['noReset'] = True
config = {
"fileName": "HUAWEI_Mate30_Pro",
"caps": desired_caps,
"config": "HUAWEI_Mate30_Pro",
"deviceName": "7HX5T19923006100",
"permission": "And 10"
}
获取配置
phoneConfigUtils.py
from config.phone import commonConfig as commonConfig
from config.phone.data.HONOR_9X import config as HONOR_9X
from config.phone.data.HUAWEI_Mate30_Pro import config as HUAWEI_Mate30_Pro
phoneConfigs = [HONOR_9X, HUAWEI_Mate30_Pro]
for i, phoneConfig in enumerate(phoneConfigs):
phoneConfig = list(phoneConfig.items()))
phoneConfigs[i] = phoneConfig
class Utils:
def getConfigByFileName(self, fileName):
config = {}
for phoneConfig in phoneConfigs:
if phoneConfig['fileName'] == fileName:
config = phoneConfig
return config
phoneConfigUtils = Utils()
注册命令行选项
conftest.py
import pytest
from config.phone.phoneConfigUtils import phoneConfigUtils
def pytest_addoption(parser):
parser.addoption( # 注册一个命令行选项
"--configFile", action="store", default="null", help="输入配置文件名称"
)
@pytest.fixture
def configData(request):
fileName = request.config.getoption("--configFile")
config = phoneConfigUtils.getConfigByFileName(fileName)
return config
命令启动Appium Server
start.bat
@echo on
title startAppiumServer
cd C:\Users\work\AppData\Local\Programs\Appium\resources\app\node_modules\appium\build\lib
start /b node --max_old_space_size=4096 main.js -a 127.0.0.1 -p 4723 --relaxed-security --session-override --default-capabilities "{\"platformName\":\"Android\",\"deviceName\":\"W4XUT20323000464\",\"app\":\"D:\\apk_url\\debug.apk\"}"
多线程调用
import threading
import pytest
import os
def job_group(fileName):
pytest.main(['-s', '-q', 'D:\\GZBAPP\\src\\group\\test_group.py', '--configFile=' + fileName])
def stop():
os.system('stop.bat')
def threading_job_group():
phoneList = ['HONOR_9X,HUAWEI_Mate30_Pro']
for phoneName in phoneList:
threading.Thread(target=job_group, args=(phoneName,)).start()
def threading_stop():
threading.Thread(target=stop).start()
if __name__ == '__main__':
os.system('start.bat')
threading_job_group()
总结,了解Appium原理后会发现可以根据设置不同的端口区分每个设备,再根据配置文件中不同手机型号作为识别标志,通过命令行方式注册命令行选项启动脚本,调用多线程实现同时对多个设备执行自动化测试。