pyAppium是python语言,基于PO模式的pytest、Appium二次封装的Android自动化框架,多进程方式在多台手机上同时执行测试,自动获取已连接设备信息,自动启动多个appium服务,同一套测试用例在不同手机上执行,用例执行失败自动截图、收集报错信息,allure插件生成测试报告
pyAppium # 项目根目录
├─app # 测试APP存放目录
├─common # 公共模块目录
├─config # 配置文件目录
├─data # 测试数据目录
├─outputs # 测试输出目录
│ ├─logs # 日志目录
│ ├─picture # 截图存放目录
│ └─reports # 测试报告存放目录
├─pageViwe # PO模式页面封装模块
└─testcase # 测试用例目录
pycharm2019 安装
python环境
安装包下载:点击去下载 自行选择相应版本
下载后点击exe,根据提示安装即可,不会自行百度
环境检测:在cmd命令终端输入:python
node 安装
node -v
jdk 安装
java -version
Android SDK 安装
adb version
appium 安装
安装 node.js,配置 node.js 的环境变量 已完成
配置国内淘宝源 npm config set registry https://registry.npm.taobao.org
安装指定版本appium :npm install -g appium@1.20.2
等待安装完成
环境检测:在cmd命令终端输入:appium -v
安装appium-doctor: npm install appium-doctor -g
作用:检查appium环境是否完整
1.仓库地址:https://gitee.com/King15800/pyAppium.git
2.下载源码:git clone https://gitee.com/King15800/pyAppium.git
3.使用pycharm 打开源码项目
4.安装项目依赖包:pip install -r requirements.txt
test_login.py
文件输入账号信息,本demo
基于学科网APP
编写App
下main.py
文件即可。启动入口说明 main.py
def run_parallel(device_info)
定义一个pytest 启动入口,根据设备进行启动,一个设备启动一个def run_parallel(device_info):
pytest.main([f"--cmdopt={device_info}",
"--alluredir", "outputs/reports/data"])
os.system("allure generate outputs/reports/data -o outputs/reports/html --clean")
device_lists = get_device_infos() # 获取连接设备信息
uninstall_app(device_lists) # 卸载APP
with Pool(len(device_lists)) as pool:
pool.map(run_parallel, device_lists)
pool.close()
pool.join()
# _*_coding:utf-8 _*_
# @Time :2021/6/21 22:33
# @Author : king
# @File :main.py
# @Software :PyCharm
from multiprocessing import Pool
import os
import pytest
from common.app_info import get_device_infos, uninstall_app
from common.appium_auto_server import close_appium
def run_parallel(device_info):
pytest.main([f"--cmdopt={device_info}",
"--alluredir", "outputs/reports/data"])
os.system("allure generate outputs/reports/data -o outputs/reports/html --clean")
if __name__ == "__main__":
device_lists = get_device_infos()
uninstall_app(device_lists)
with Pool(len(device_lists)) as pool:
pool.map(run_parallel, device_lists)
pool.close()
pool.join()
driver实现 base_driver.py
class BaseDriver:
def __init__(self, device_info):
self.device_info = device_info
cmd = "start /b appium -a 127.0.0.1 -p {0} -bp {1}".format(self.device_info["server_port"],
self.device_info["server_port"] + 1)
open_appium(cmd, self.device_info["server_port"])
def base_driver(self, automationName="appium"):
fp = open(f"{configPath}//caps.yml", encoding='utf-8')
# 平台名称、包名、Activity名称、超时时间、是否重置、server_ip、
desired_caps = yaml.load(fp, Loader=yaml.FullLoader)
# 设备名称
desired_caps["deviceName"] = self.device_info['device']
# 版本信息
desired_caps["platform_version"] = get_devices_version(desired_caps["deviceName"])
app_path = os.path.join(appPath, get_app_name(appPath))
desired_caps['app'] = app_path
desired_caps['appPackage'] = get_app_package_name()
desired_caps['appActivity'] = get_app_launchable_activity()
# udid
desired_caps["udid"] = self.device_info['device']
# 系统端口号
desired_caps["systemPort"] = self.device_info["system_port"]
if automationName != "appium":
desired_caps["automationName"] = automationName
driver = webdriver.Remote(f"http://127.0.0.1:{self.device_info['server_port']}/wd/hub",
desired_capabilities=desired_caps)
return driver
核心conftest文件 conftest.py
from common.base_driver import BaseDriver
import pytest
import random
from pageViwe.loginPage import LoginPage
driver = None
def pytest_addoption(parser):
parser.addoption("--cmdopt", action="store", default="device_info", help=None)
@pytest.fixture(scope='session')
def cmdopt(pytestconfig):
# 两种写法
return pytestconfig.getoption("--cmdopt")
# return pytestconfig.option.cmdopt
# 定义公共的fixture
@pytest.fixture(scope='session')
def common_driver(cmdopt):
global driver
base_driver = BaseDriver(eval(cmdopt))
driver = base_driver.base_driver()
lg = LoginPage(driver)
yield lg
driver.close_app()
driver.quit()
@pytest.fixture
def device(cmdopt):
yield eval(cmdopt)
# 报告中区分多设备执行结果
def pytest_itemcollected(item):
item._nodeid = str(random.randint(1, 1000)) + '_' + item . _nodeid
2021-06-24-23-10-15-basePage.py-basePage-find_element-33-INFO-同意协议 页面开始查找元素('id', 'com.xkw.client:id/agree_yes') 2021-06-24-23-10-16-basePage.py-basePage-find_element-36-INFO-同意协议 页面查找元素('id', 'com.xkw.client:id/agree_yes')成功! 2021-06-24-23-10-16-basePage.py-basePage-click_element-61-INFO-同意协议 页面点击元素('id', 'com.xkw.client:id/agree_yes') 2021-06-24-23-10-16-basePage.py-basePage-click_element-63-INFO-同意协议 页面点击元素('id', 'com.xkw.client:id/agree_yes')成功! 2021-06-24-23-10-17-basePage.py-basePage-find_element-36-INFO-同意协议 页面查找元素('id', 'com.xkw.client:id/agree_yes')成功! 2021-06-24-23-10-17-basePage.py-basePage-click_element-61-INFO-同意协议 页面点击元素('id', 'com.xkw.client:id/agree_yes') 2021-06-24-23-10-17-basePage.py-basePage-click_element-63-INFO-同意协议 页面点击元素('id', 'com.xkw.client:id/agree_yes')成功! 2021-06-24-23-10-18-basePage.py-basePage-is_element_exist-105-INFO-发现 页面开始查找元素 ('id', 'com.xkw.client:id/discover_search_box') 2021-06-24-23-10-18-basePage.py-basePage-is_element_exist-108-INFO-发现 页面查找元素 ('id', 'com.xkw.client:id/discover_search_box')成功! 2021-06-24-23-10-18-basePage.py-basePage-get_size-121-INFO-开始获取设备屏幕大小。 2021-06-24-23-10-18-basePage.py-basePage-get_size-125-INFO-获取设备屏幕大小完成。(720, 1280) 2021-06-24-23-10-18-basePage.py-basePage-swipe_to_up-167-INFO-首页 页面开始进行上滑 2021-06-24-23-10-19-basePage.py-basePage-is_element_exist-105-INFO-发现 页面开始查找元素 ('id', 'com.xkw.client:id/discover_search_box') 2021-06-24-23-10-19-basePage.py-basePage-find_element-36-INFO-同意协议 页面查找元素('id', 'com.xkw.client:id/agree_yes')成功! 2021-06-24-23-10-19-basePage.py-basePage-click_element-61-INFO-同意协议 页面点击元素('id', 'com.xkw.client:id/agree_yes') 2021-06-24-23-10-19-basePage.py-basePage-click_element-63-INFO-同意协议 页面点击元素('id', 'com.xkw.client:id/agree_yes')成功! 2021-06-24-23-10-19-basePage.py-basePage-is_element_exist-108-INFO-发现 页面查找元素 ('id', 'com.xkw.client:id/discover_search_box')成功! 2021-06-24-23-10-19-basePage.py-basePage-get_size-121-INFO-开始获取设备屏幕大小。 2021-06-24-23-10-19-basePage.py-basePage-get_size-125-INFO-获取设备屏幕大小完成。(720, 1280) 2021-06-24-23-10-19-basePage.py-basePage-swipe_to_up-167-INFO-首页 页面开始进行上滑 2021-06-24-23-10-20-basePage.py-basePage-swipe_to_up-169-INFO-首页 页面开始上滑完成。
注意点
pytest
的自带日志模块,修改pytest
自带loging文件的写入模式,保证记录完整日志信息,文件路径F:\appium_env\Lib\site-packages\_pytest\logging.py
需要根据自己环境地址进入mode='w'
改成 mode='a'
在文件505行左右 if log_file:
self.log_file_handler = logging.FileHandler(
log_file, mode="a", encoding="UTF-8"
)
如果您觉得对你有帮助,可以进行留言评论 有任何问题,可以联系我,进行询问,不限于此框架问题
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。