• 【第四篇】XiaoZaiMultiAutoAiDevices之核心机制


    【第四篇】XiaoZaiMultiAutoAiDevices之核心机制

    一、unittest改造

    在上一期说到主要的流程和部分核心运行流程,这一期我们主讲:如何通过外部参数指定脚本运行指定设备

    测试框架传参,可能一部分同学会想到unittest的DDT,使用pytest相关装饰器和各种外部文件的数据传入方式。

    在当前这套框架中,我们是将设备在index.py中加入到进程中,再由进程去调用RunTestCase方法,在RunTestCase方法中,我们将进程中传入的设备ID再传入到TestCase中,实现一个动态获取动态执行。

    那么,如何在TestCase文件外部传入一个值进入TestCase内部,并且进行使用呢?

    这里我自己通过查阅资料,封装了一套方法,文件路径在common\ParameterizedTestCase.py

    (1) 如何使用ParameterizedTestCase

    可参考框架中TestCase\Demo文件夹中的TestCase文件,均使用了ParameterizedTestCase

    1.在需要使用TestCase文件中导入ParameterizedTestCase类

    from common.ParameterizedTestCase import ParameterizedTestCase
    
    • 1

    2、在编写TestCase时,继承ParameterizedTestCase类

    class TESTDemo_1(ParameterizedTestCase):
        '第一个测试文件'
        # @unittest.skip
        def test001_startAPP(self):
            '001进入第一个页面'
            print(f"当前运行的设备为:{self.device_id}")
            print('001进入第一个页面')
        # @unittest.skip
        def test002_Authorization(self):
            '''001_进行授权'''
            print('001第二个测试用例')
    
        def test004_IosAtt(self):
            '''001_ios弹出ATT弹窗,点击"允许跟踪"按钮'''
            print('001_ios弹出ATT弹窗,点击"允许跟踪"按钮')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    (2) ParameterizedTestCase 源码解析

    我框架源码有详细注释

    # -*- coding: utf-8 -*-
    '''
    @Time : 2022/9/19 17:26
    @Author : Vincent.xiaozai
    @Email : Lvan826199@163.com
    @File : ParameterizedTestCase.py
    '''
    __author__ = "梦无矶小仔"
    
    import unittest
    
    class ParameterizedTestCase(unittest.TestCase):
        """ 继承unittest.TestCase类,ParameterizedTestCase类可以进行参数化
            使用时直接继承ParameterizedTestCase类
            注意:methodName不要赋值,否则test不生效
        """
        def __init__(self, methodName, device_id=None):
            super(ParameterizedTestCase, self).__init__(methodName)
            self.device_id = device_id
    
        @staticmethod
        def parameterize(testcase_class, device_id=None):
            """ 创建一个套件,其中包含给定的测试类,参数可以自己定义单个或多个
            :return 返回测试套件
            :device_id 表示传入的参数,可以自定义,需要注意的是,在init中需要同步更新
            """
            testloader = unittest.TestLoader()
            testnames = testloader.getTestCaseNames(testcase_class)
            suite = unittest.TestSuite()
            for name in testnames:
                suite.addTest(testcase_class(name, device_id=device_id))
            return suite
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    二、外部传参入TestCase

    在前面我们将需要接收外部参数的测试类继承了ParameterizedTestCase,在ParameterizedTestCase 中我们可以自定义接收的参数,本框架为了便于理解只定义了一个device_id变量,如果想要传入多个参数,可以自行采用*args**kwargs进行传值。

    (1)定义接收变量字典

    在TestCase类外定义一个字典,进行全局变量控制,如Demo示例中为:

    controlparams = {'control':1} # 用作控制器
    
    • 1

    在这里control作为控制器,防止设备频繁进行初始化。

    (2)setUp进行初始化

    Demo中为IOS的初始化,其他初始化可以参考index.py中的代码。setUp代码如下:

    def setUp(self):
        u'''这里放需要在每条用例前执行的部分'''
        # 前段部分用于初始化连接设备,这个部分的作用就是避免设备多次重新连接,只会连接一次
        if controlparams['control'] == 1 :
            self.ios = IOS("http+usbmux://" + self.device_id)
            self.c = wda.Client("http+usbmux://{udid}".format(udid=self.device_id))
            controlparams['ios'] = self.ios
            controlparams['c'] = self.c
            controlparams['control'] = 2
        # 每次执行用例前,需要从控制参数里面进行取出(但不会进行重新连接)
        self.ios = controlparams['ios']
        self.c = controlparams['c']
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    这里我们看到了一个self.device_id,这个值就是我们在ParameterizedTestCase 中定义的外部传入的值,在TestCase可以直接用self进行获取。

    其他的self.ios是使用的airtest-core-ios中的ios进行ios的一些原生控件操作初始化。

    self.c则是使用的wda进行初始化,使用者可以自行选择一个,也可以全都用。(Android请不要讲uiautomator2和airtest一起初始化使用,会发生冲突。)

    (3)Case中进行使用

    在每个小case中,我们直接使用self.属性就可以啦,因为所有的步骤都是一样的,初始化的时候可以cv框架中Demo的代码就行,如果想要自己改造,可以看下系列教程。

    三、IOS相关封装

    common\IOSAppOperate.py封装了IOS相关操作。

    1.自动切换更改Apple Store 的账号密码

    2.自动切换更改沙盒账号密码

    3.自动前往TestFlight下载相关应用

    相关代码可自行下载框架源码进行查阅。

  • 相关阅读:
    前端-(6)
    Mysql——压缩包方式安装教程
    nginx代理后如何获取用户真实访问的ip,以及访问耗时接口是nginx报504问题处理
    java/spring 控制层controller接口请求参数为list<>和字符串String,前端参数应该怎么传?- 教你
    Swoole v6 能否让 PHP 再次伟大?
    Java面试题及答案整理(2022年140道)持续更新
    【Java】RedisTemplate来控制某段时间内执行最大次数
    rust编程-通用编程概念(chapter 3.4 & 3.5 注释和控制语句)
    如何保护你的网络安全?
    瑞_23种设计模式_策略模式
  • 原文地址:https://blog.csdn.net/qq_46158060/article/details/128093893