Appium 并发多进程基于 Pytest框架

前言:

之前通过重写unittest的初始化方法加入设备参数进行并发,实现了基于unittest的appium多设备并发,但是考虑到unittest的框架实在过于简陋,也不方便后期的Jenkins的持续集成,所以想换一个框架来使用。

那么通过调研,pyhon+pytest+allure 这套框架很不错,pytest是一个单元测试框架,他可以集成很多插件,包括出错重试,参数化,等。在此特别是基于他的allure插件,能够和Jenkins完美兼容,生成美观强大的测试报告。

改造思路:

pytest框架和unittest框架明显不同,通过命令行启动,读取响应目录下的test开头的文件,进行执行用例。

而unittest却是通过将用例加载到TestSuite中,运行随测试集来执行用例

所以这边多进程就要换一种思路进行了。

基于pytest的结构和运行方式,那么思路如下:

运行方式:

1. pytest目录下会先加载conftest.py运行。

2. 该目录下加载test开头的py文件

3. 加载文件中Test开头的类

4. 加载Test类下test开头的方法

5. 通过命令行pytest.main([1, 2 ,3])带入1 2 3参数进行运行

解决思路:

1. 通过命令行把不同设备的参数传递给conftest.py

2. conftest中,使用传递过来的设备参数,连接设备到appium,并生成driver对象

3. 在各自的测试类和测试方法中,调用driver对象,进行测试操作

4. 生成allure测试报告

实现:

1. 通过命令行传递参数:

run中的设备池:

def devices_Pool():
    devices_list = []
    for i in range(0, len(getDevices())):
        _initApp = {}
        _initCaps = {}
        _initApp["devices"] = getDevices()[i]
        _initCaps["deviceName"] = getDevices()[i]
        _initCaps["platformVersion"] = getPhoneInfo(devices=_initCaps["deviceName"])["release"]
        _initCaps["platformName"] = "Android"
        _initApp["port"] = str(random.randint(4700, 4900))
        _initApp["bport"] = str(random.randint(4700, 4900))
        _initApp["systemPort"] = str(random.randint(4700, 4900))
        _initCaps["automationName"] = "UiAutomator2"
        _initCaps["appPackage"] = ‘cn.vsx.vc‘
        _initCaps["appActivity"] = ‘.activity.RegistActivity‘
        _initApp["Caps"] = _initCaps
        devices_list.append(_initApp)
    print(len(getDevices()))
    print(len(devices_list))
    return devices_list

run中,多进程调用启动命令行,并传递参数:

def runnerPool(device_list):
    getdevice = getDevices()
    with ProcessPoolExecutor(len(getdevice)) as pool:
        pool.map(runPytest, device_list)

def runPytest(device):
    print(f"cmdopt is {device}")
    report = f"report-{device[‘Caps‘][‘deviceName‘]}".split(":", 1)[0]
    try:
        os.system(f"del /s /q E:\\appium-pytest\\{report}")
        time.sleep(1)
        os.system(f"rd /s /q E:\\appium-pytest\\{report}")
        time.sleep(1)
        print(f"{report} report has deleted")
    except:
        print("no directory existed")
    finally:
        print(f"pool run device is {device[‘devices‘]}")
        pytest.main(["../TestCases/", f"--cmdopt={device}", "--alluredir", f"../{report}/xml"])
        time.sleep(1)
        os.system(f"allure generate ../{report}/xml -o ../{report}/html")

conftest文件中,获取命令行传递过来的参数:

def pytest_addoption(parser):
    parser.addoption("--cmdopt", action="store", default="device", help="None")

@pytest.fixture(scope="session")
def cmdopt(request):
    return request.config.getoption("--cmdopt")

conftest中通过传递的参数,生成连接对象:

@pytest.fixture(scope="session")
def connectDevice(cmdopt):
    device = eval(cmdopt)
    device_caps = {}
    device_caps["platformVersion"] = getPhoneInfo(device["Caps"]["deviceName"])["release"]
    device_caps["platformName"] = "Android"
    device_caps["automationName"] = "UiAutomator2"
    device_caps["deviceName"] = device["Caps"][‘deviceName‘]
    device_caps["udid"] = device["Caps"][‘deviceName‘]
    device_caps["appPackage"] = "cn.vsx.vc"
    device_caps["appActivity"] = ".activity.RegistActivity"
    device_caps["noReset"] = True
    device_caps["noSign"] = True
    device_caps["unicodeKeyboard"] = True
    device_caps["resetKeyboard"] = True
    device_caps["systemPort"] = int(device["systemPort"])
    remote = "http://127.0.0.1:" + str(device["port"]) + "/wd/hub"
    print(f"wo shi pytest {device_caps}")
    driver = webdriver.Remote(remote, device_caps)
    return driver

测试用例中,使用对象来进行操作:

class Test_groupCall():
    @allure.feature("group_call")
    @allure.story("login")
    def test001_login(self, connectDevice):
        ‘‘‘登入选择单位‘‘‘
        WebDriverWait(connectDevice, 10).until(
            lambda x: x.find_element_by_xpath(
                "//android.widget.TextView[contains(@text, ‘选择单位‘)]").is_displayed())  # 验证等待10秒超时
        x = connectDevice.get_window_size()[‘width‘]  # 获取当前屏幕宽
        y = connectDevice.get_window_size()[‘height‘]  # 获取当前屏幕高
        a, b = 170 / 768, 790 / 1184  # 选择单位222系数
        connectDevice.find_element_by_xpath("//android.widget.TextView[contains(@text, ‘选择单位‘)]").click()

最后:

多设备连接时,一定要注意给每个desired_caps中加入每个设备自己的systemPort,否则会连接不上多设备,至此改造成功,最后生成的报告也让人满意:

原文地址:https://www.cnblogs.com/grandlulu/p/10331612.html

时间: 2024-10-10 01:55:20

Appium 并发多进程基于 Pytest框架的相关文章

Java并发编程之---Lock框架详解

Java 并发开发:Lock 框架详解 摘要: 我们已经知道,synchronized 是Java的关键字,是Java的内置特性,在JVM层面实现了对临界资源的同步互斥访问,但 synchronized 粒度有些大,在处理实际问题时存在诸多局限性,比如响应中断等.Lock 提供了比 synchronized更广泛的锁操作,它能以更优雅的方式处理线程同步问题.本文以synchronized与Lock的对比为切入点,对Java中的Lock框架的枝干部分进行了详细介绍,最后给出了锁的一些相关概念. 一

《开源框架那点事儿13》:基于开源框架做应用是未来中小型软件公司的发展趋势

在我的周边朋友身边就发生过这样的事情: 故事1:A君在北京从事Java开发好多年了,萌发了创业的念头,想组建了一个开发团队想大干一场.但是慢慢发现,构建一个有战斗力的团队真不容易.后来技术团队的组建初步有了起色,但是技术路线却非常难成一致意见.折腾来折腾去,把有点上道的技术人员都折腾得跳槽了.费了巨高的成本搞了一个架构师,就是利用SSH框架搭建了一个开发环境,数据量小,业务初期还是不错的,但是当业务快速增长的时候,运行速度就无法满足需要了.是重新来过还是在SSH的基础上继续折腾,非常难以抉择!

基于netty框架的Socket传输

一.Netty框架介绍 什么是netty?先看下百度百科的解释: Netty是由JBOSS提供的一个java开源框架.Netty提供异步的.事件驱动的网络应用程序框架和工具,用以快速开发高性能.高可靠性的网络服务器和客户端程序. 也就是说,Netty 是一个基于NIO的客户.服务器端编程框架,使用Netty 可以确保你快速和简单的开发出一个网络应用,例如实现了某种协议的客户,服务端应用.Netty相当简化和流线化了网络应用的编程开发过程,例如,TCP和UDP的socket服务开发. "快速&qu

基于MyBatis框架链接数据库

基于Mybatis框架 特点:给予MyBatis框架半成品 站在巨人肩膀上 连接访问数据库,封装成工具类 方便调用连接 减少代码的冗余 提高效率 支持多线程并发访问 public class BatisUtil { private static final ThreadLocal<SqlSession> thl = new ThreadLocal<SqlSession>(); private static SqlSessionFactoryBuilder builder =null

一个基于SSM框架开发的高并发电商秒杀Web系统

0 前言 一个基于SSM框架的高并发秒杀系统采用IDEA+Maven+SSM+Mysql+Redis+Jetty.Bootstrap/Jquery开发. 通过这个小项目,理清了基于SSM框架开发Web应用的流程以及常见的避坑方法,并在最后简单采用了Redis缓存以及Mysql Procedure对项目进行了高并发优化. 接下来从DAO层.Service层.Web层开发以及高并发优化4个方面梳理整个项目开发过程. 源码地址https://github.com/Allegr0/seckill 项目准

基于Scrapy框架的Python新闻爬虫

概述 该项目是基于Scrapy框架的Python新闻爬虫,能够爬取网易,搜狐,凤凰和澎湃网站上的新闻,将标题,内容,评论,时间等内容整理并保存到本地 详细 代码下载:http://www.demodashi.com/demo/13933.html 一.开发背景 Python作为数据处理方面的一把好手,近年来的热度不断增长.网络爬虫可以说是Python最具代表性的应用之一,那么通过网络爬虫来学习Python以及网络和数据处理的相关内容可以说是再合适不过了. Scrapy是由Python语言开发的一

基于Bootstrap框架的临床数据管理系统的设计与开发

    基于Bootstrap框架的临床数据管理系统的设计与开发     2018年11月10日 目  录 第一章绪论... 6 1.1 选题背景及其意义... 6 1.2国内外研究现状... 7 1.2.1 临床大数据管理系统发展现状... 7 1.2.2医疗电子表单管理发展现状... 8 1.3研究目标... 9 1.4 研究内容... 10 1.5论文整体结构... 10 第二章相关技术研究... 12 2.1 AngularJS技术简述... 12 2.2 RESTful API +sw

pytest框架之fixture详细使用

本人之前写了一套基于unnitest框架的UI自动化框架,但是发现了pytest框架之后觉得unnitest太low,现在重头开始学pytest框架,一边学习一边记录,和大家分享,话不多说,那就先从pytest框架的精髓fixture说起吧! 简介: fixture区别于unnitest的传统单元测试(setup/teardown)有显著改进: 1.有独立的命名,并通过声明它们从测试函数.模块.类或整个项目中的使用来激活. 2.按模块化的方式实现,每个fixture都可以互相调用. 3.fixt

学习 python 的 pytest 框架需要的基础知识和学习准备

学习 python 的 pytest 框架需要的基础知识和学习准备测试从业者学习 python 应该掌握的内容: 首先是变量和数据类型,其次列表.字典以及 Json 的一些处理,再者就是循环 判断以及函数或类这些内容. 其中的重点: 1.循环判断以及字典这块是重点 2.函数和类,类的学习这块要花较多时间去学习它的集成.封装.多态等,这 是一个不断积累的过程,先把前面的东西弄清楚了,然后去学如何用函数的方 式去处理这些比较基础的内容 python 大纲学习内容详见另一篇文章 扫下方二维码 电商项目