2 Star 19 Fork 8

king / pyAppium

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
readme.md 12.81 KB
一键复制 编辑 原始数据 按行查看 历史
king 提交于 2021-07-19 09:58 . update readme.md.

pyAppium

项目介绍

pyAppium是python语言,基于PO模式的pytest、Appium二次封装的Android自动化框架,多进程方式在多台手机上同时执行测试,自动获取已连接设备信息,自动启动多个appium服务,同一套测试用例在不同手机上执行,用例执行失败自动截图、收集报错信息,allure插件生成测试报告

框架目录说明

pyAppium		# 项目根目录
├─app			# 测试APP存放目录
├─common		# 公共模块目录
├─config		# 配置文件目录
├─data			# 测试数据目录
├─outputs		# 测试输出目录
│  ├─logs		# 日志目录
│  ├─picture	# 截图存放目录
│  └─reports	# 测试报告存放目录
├─pageViwe		# PO模式页面封装模块
└─testcase		# 测试用例目录

主要功能

  1. 自动启动appium server和杀掉appium server
  2. 自动获取电脑连接设备信息,如设备版本、设备udid
  3. 自动检测端口是否可用、释放占用端口
  4. 自动获取测试APP应用相关信息,如:appPackage、launchable_activity
  5. 自动安装APP和卸载APP
  6. 测试用例无需配置,自动获取用例执行,测试人员只需编写相关case
  7. 用例执行失败自动截图、收集错误日志信息,自动加到测试报告对应case下面
  8. 启动一次APP,执行所有测试用例,缩短测试用例执行间隔,提高测试执行效率
  9. 多进程方式在多台手机上同时执行测试,大幅提高测试效率

框架使用

测试环境

  • win10 64 pycharm2019
  • python 3.7.0 及以上
  • node v12.16.3
  • appium1.20.2
  • java version "1.8.0_181"
  • Android SDK 百度云分享地址 密码:6666

环境安装

  • pycharm2019 安装

    • 自行百度安装,或者留言联系。
  • python环境

  • 安装包下载:点击去下载 自行选择相应版本

  • 下载后点击exe,根据提示安装即可,不会自行百度

  • 环境检测:在cmd命令终端输入:python pyth版本

  • node 安装

    • 安装包下载:点击去下载 自行选择相应版本
    • 下载后点击exe,根据提示安装即可,不会自行百度
    • 环境检测:在cmd命令终端输入:node -v node 版本检测
  • jdk 安装

    • 安装包下载:点击去下载 自行选择相应版本
    • 下载后点击exe,根据提示安装即可,不会自行百度
    • 配置环境变量:
      • 新建环境变量:JAVA_HOME 如值为:D:\Java\jdk1.8.0_181\bin
      • 在系统变量 Path 的值的前面加入以下内容:%JAVA_HOME%\bin
    • 环境检测:在cmd命令终端输入:java -version java环境检测
  • Android SDK 安装

    • 从上面百度云下载 Android sdk 解压到一个目录,不要包含空格、中文路径
    • 新建环境变量:ANDROID_HOME 值为:F:\Andriod_SDK
    • 在系统变量 Path 的值的前面加入以下内容:%ANDROID_HOME%\platform-tools、%ANDROID_HOME%\tools
    • 环境检测:在cmd命令终端输入:adb version Android SDK检测
  • 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 版本查看

    • 安装appium-doctor: npm install appium-doctor -g 作用:检查appium环境是否完整 appium-doctor 检查

下载框架源码

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,放到项目目录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-首页 页面开始上滑完成。

测试报告

  • 执行时启动了3台模拟器,case 标题动态生成,可以自行修改,目前是功能名称+设备udid 测试用例收集结果 执行失败自动截图加入到报告

注意点

  • 由于使用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"
            )

未来规划

  • 集成到Jenkins
  • 不同机器能够采用不同数据
  • 可以对于无线连接手机进行测试
  • appium server远程分布式调用执行

有问题,联系方式

  • QQ:772084279 备注 pyAppium
  • 个人微信公众号:微信号公众号

如果您觉得对你有帮助,可以进行留言评论 有任何问题,可以联系我,进行询问,不限于此框架问题

Python
1
https://gitee.com/King15800/pyAppium.git
git@gitee.com:King15800/pyAppium.git
King15800
pyAppium
pyAppium
master

搜索帮助