首页 > 其他分享 >如何在自动化测试中应用装饰器、多线程优化自动化架构?

如何在自动化测试中应用装饰器、多线程优化自动化架构?

时间:2024-09-22 19:49:27浏览次数:3  
标签:架构 函数 pytest 自动化 print 测试用例 多线程 装饰 def

1、装饰器概念

        装饰器是Python中用于修改函数或类的语法结构的工具。它以函数作为输入参数,并返回一个函数作为一个输出函数,在不改变原有函数的代码情况下,给函数增加功能或改变函数行为。

        装饰器的使用方式是在函数定义的上方使用 @decorator_name 的形式将装饰器应用到函数上,这样定义的函数在被调用时会先执行装饰器函数,再执行原始函数。常见的装饰器有类装饰器、函数装饰器、属性装饰器等。

        装饰器本身需要接受一个被装饰的对象作为参数,该参数通常为函数、方法、类等对象。

        装饰器需要返回一个对象,该对象可以是 经过处理的原参数对象、一个包装且类似原参数的对象

1.1 最简单的装饰器

def my_decorator(func):
    def wrapper():
        print("Before the function is called.")
        func()
        print("After the function is called.")
    return wrapper


@my_decorator
def say_hello():
    print("Hello!")


say_hello()

 如代码所示:

1、当我们调用被装饰器修饰的函数的时候,首先会把 say_hello 的函数传入 my_decorator
的 func 参数中,然后再去执行内部的 wrapper 函数(在这个函数内部就会操作很多东西,比如增删改等操作),最后返回 wrapper 函数。

2、实际上我们调用的 say helo 函数没有被执行,那这里为什么执行了呢?是因为 wrapper函数里面又调用了一次它,如果不调用,那么 say hello 函数就是一个装饰,但是通常情况下都会调用一次来达到我们的一些特殊目的。

1.2 用于修改对象和函数的装饰器 

def wrap(obj):
    obj.name = 'python'
    return obj

@wrap
class Bar(object):
    def __init__(self, name):
        pass

print(Bar.name)

@wrap
def foo():
    pass

print(foo.name)

 可以看到实际的使用过程中,warp装饰器已经成功的给Bar对象添加了name属性。除了给类对象添加属性之外,它还可以给函数对象添加属性。

1.3 用于模拟对象的装饰器-函数装饰器【重点中的重点】

用于模拟对象的装饰器--函数装饰器
上面例子中的装饰器,是直接修改了传入对象,而装饰器最常用的方式却是模拟一个传入对象。即返回一个和原对象相似的对象(即调用接口完全一样的另一个对象),并且该模拟对象是包装了原对象在内的。具体代码如下:

def outer(func):
    def inner():
        print("Hello inner")
        func()
    return inner
@outer
def foo():
    print("Hello foo")

print(foo.__name__)
foo()

上面是一个函数装饰器,即用来修饰函数的装饰器因为它返回了一个模拟func对象的inner对象。而这里inner对象是一个函数,所以这个装饰器只能装饰函数。(因为inner对象只能模拟func这样的函数对象,不能模拟class对象)
可以看到首先打印的是 foo._name_代码,注意内容是inner而不是foo(说明其本质上是inner函数);其次打印的时候,先打印inner函数中的内容,后打印foo函数中的内容。

Python 中被装饰后的函数,函数名等函数属性会发生改变(相当于另一个函数了)所以,Python 的functools 包中提供了一个叫 wraps 的装饰器来解决该问题。它能使其保留原有函数的结构。 

1.4 用于模拟对象的装饰器

def outer(obj):
    def inner(self):
        print('hello inner')
        obj(self)
    return inner

class Zoo(object):
    def _init_(self):
        pass
    @outer
    def zoo(self):
        print('hello zoo')
zoo = Zoo()
print(zoo.zoo.__name__)
zoo.zoo()

 可以看到类方法装饰器和函数装饰器,唯一的区别是多了一个默认的self参数,这是因为类方法本身比函数多一个参数。

2、装饰器的应用

Python 装饰器的应用比较广泛,大部分场景的公共处理逻辑都可以使用装饰器去简化。(使用上类似于 JAVA 中的注解)一般比较常见的场景比如:

  • 日志记录
  • 权限验证
  • 单例模式
  • 竞争资源管理
  • Fixture

2.1 装饰器在pytest中的使用@pytest.fixture 

        比如 conftest 胶水文件中可以写 driver 以及写数据库连接操作等,使用装饰器+生成器假设我们有一个需要连接数据库执行查询操作的测试用例集合。
        在每个测试用例执行前,我们需要先建立数据库连接,并在每个测试用例执行结束后,关闭数据库连接。这时,我们可以使用 @pytest.fixture 装饰器定义一个名为 db_conn 的fixture 函数,它返回一个数据库连接对象,然后在测试用例函数中通过参数引用该 fixture函数即可获得连接对象。
        我们可以非常方便地对测试用例进行初始化和清理工作,避免几余代码,并且可以重复利用测试代码和资源。
代码示例如下: 

import pytest
import psycopg2
@pytest.fixture(scope='function')
def db_conn():
    conn = psycopg2.connect(database="testdb",user="testuser",
password="testpass'host="localhost",port="5432")
    yield conn
    conn.close()

def test_query1(db_conn):
    cursor =db_conn.cursor()
    cursor.execute('SELECT * FROM table1')
    result = cursor.fetchall()
    assert len(result)>0

def test_query2(db_conn):
    cursor=db_conn.cursor()
    cursor.execute('SELECT * FROM table2')
    result = cursor.fetchall()
    assert len(result)>0

2.2 pytest中的@pytest.mark 

它可用于给测试用例打标签,方便统计测试结果和过滤测试用例。比如,给测试用例打上 slow、fast、smoke 等标签,可以通过 pytest 的命令行参数 pytest -m 进行选择性测试。

import pytest

@pytest.mark.slow
def test_case1():
    pass


@pytest.mark.fast
def test_case2():
    pass


@pytest.mark.smoke
def test_case3():
    pass

pytest .\1.py -m smoke 

 

如图,只有标记为smoke的被执行了 

2.3 @pytest.mark.paramsmetrize在pytest中的使用(参数化)

它可用于参数化测试用例,即对同一种情况下的不同输入进行测试,可以减少重复的测试代码和测试用例数量。

import pytest
@pytest.mark.parametrize('a, b,c',[(1,2,3),(4,5,9),(7,8, 15)])
def test add(a, b, c):
        assert a+b==C 

 2.4 pytest中的@pytest.hookimpl中的使用

它可以定义 pytest 的 hook 函数,hook 函数用于在 pytest 的执行过程中被调用,以处理测试收集、运行、报告等各个环节。
 

import pytest
@pytest.hookimpl
def pytest runtest call(item):
        print(f"test function fitem.name} is about to run...")

把这个函数放到 conftest 中就可以实现功能了

 每当我们跑一个用例,就会打印一些日志内容

2.5 python 的@property 装饰器的介绍与使用

python 的@property 是 python 的一种装饰器,是用来修饰方法的。

作用:
我们可以使用@property 装饰器来创建只读属性,@property 装饰器会将方法转换为相同名称的只读属性,可以与所定义的属性配合使用,这样可以防止属性被修改。 

简而言之:

1.可以把方法变为属性

2.防止属性被修改

class DataSet(object):
    @property
    def method _with_property(self):
##含有@property
        return 15
    def method without property(self):##不含@property
        return 15
I= DataSet()
print(l.method with _property)
#加了@property 后,可以用调用属性的形式来调用方法,后面不需要加()
print(l.method without property())
#没有加@property,必须使用正常的调用方法的形式,即在后面加()

3、多线程编程思想 

1、如果你的测试用例是 I/O 密集型的,比如页面加载、数据输入等操作,那么使用多线程可以显著提高测试执行的效率。因为在等待I/O操作完成的时间内,可以切换到其他线程执行任务,避免浪费 CPU 资源,简单来说就是频繁输入加载等操作,就很适合多线程,不过要注意电脑的配置
2、如果你的测试用例需要在不同的浏览器或者不同的页面之间进行切换,那么使用多
线程可以避免在切换时出现页面卡顿或者响应延迟的问题。

3、如果除开这上面的操作,如果强行使用多线程开发,可能还会导致性能下降,因为需要频繁去调度 cpu,切换线程,线程间切换的开销可能会抵消掉并行处理所获得的性能提升

使用方法:使用 pytest-xdist 插件来实现多线程并发执行测试用例(自动分配每个线程要执行哪些测试用例)

当运行测试时,pytest-xdist 插件会自动将测试用例分发给多个线程并发执行,每个线程都可以独立打开一个网页运行测试用例,从而提高整体的执行效率。
使用 pytest 单线程运行测试用例:

pytest无头模式

在无头模式中,五个用例执行快了四秒,我为每一个用例都分配了一个线程去执行,这样会更快,因为会并发的去执行这五个测试用例。cpu不断的调度实现宏观的并发,微观实际上还是并行)
在有头模式中,打开了五个浏览器一起执行 88 个测试用例,相当于五个人一起执行测试用例,速度肯定是更快的,快了30s。(cpu不断的调度实现宏观的并发,微观实际上还是并行)
用法详解:
1、pytest-n 2:使用 2 个进程并行运行测试,如果有四个用例,1,3用例给第一个线程执行,2,4用例给第二个线程执行。
2、pytest -n auto:自动检测可用的 CPU 核心数量,并使用对应数量的进程并行运行测试。这是一种常用的设置,可以充分利用计算资源。
3、pytest -n 4-dist=loadfile:使用 4个进程并行运行测试,并使用"oadfile"分发插件进行测试运行。
使用 -n 参数,pytest 可以在多个进程中同时执行测试,从而加快整体测试运行时间,特别是在拥有多个 CPU 核心或处理器的计算机上。建议在实际使用时,根据自己的系统配置和测试需求,调整-n参数的值来获得最佳的性能和效果

4、数据驱动测试,yaml数据源 

标签:架构,函数,pytest,自动化,print,测试用例,多线程,装饰,def
From: https://blog.csdn.net/m0_67329659/article/details/142303443

相关文章

  • 数据中台陨落,数据飞轮崛起:新时代的数据架构选择
    在科技迭代的潮流中,企业对数据的处理和利用已经从单纯的存储转变为如何高效提升业务决策和操作效率。数据中台曾经作为企业数据管理的救星受到了极大的推崇,旨在统一企业内部数据的收集、存储和管理,实现数据资产的集中控制和高效利用。然而,现实往往与理想有差距,数据中台在实际运用中......
  • 数据中台难题与数据飞轮的崛起:探索未来数据架构的变革
    在近年的数据管理领域,数据中台一度被视为企业解决数据孤岛、提升数据利用效率的利器。然而,随着时间推移,数据中台的光环有所褪色,不少企业开始面临新的挑战。原因多端,包括但不限于高成本投入、实施复杂、以及数据活用的实际效果不佳。企业投入巨大,期望通过构建中台来整合各类数据资源......
  • 线程的概念与多线程模型
    目录线程的概念线程的属性多线程模型一对多模型​编辑​编辑​编辑多对一模型多对多模型​编辑​编辑线程的概念首先先了解有线程和没线程的区别没线程的进程:进程间虽可以相互切换并发执行,但每个进程内的程序不能相互切换并发执行。就比如你可以一边听音乐一遍聊微......
  • 浅谈OB高可用架构下的RTO与RPO
    OB从4.x.x版本开始提供了两副本加仲裁节点的高可用架构,比对三副本架构可以将第三个zone(机房)的成本降到极低,仅需要一个小规格的虚拟机即可。对于没有三个数据副本部署要求的业务来说,可以节约三分之一的服务器资源。因此对于同城多机房部署下的数据库架构,三副本架构和两副本加仲裁节......
  • 数据飞轮与数据中台:未来数据架构的进化论
    在数据驱动的商业世界中,‘数据中台’与‘数据飞轮’是两个高频出现且深受关注的概念。然而,这两者之间具有本质的连接与区别,通过深入分析和对比,我们可以更好地悟出数据驱动战略的核心要义。本文将探讨数据飞轮是否为数据中台的高阶形态,并通过具体的业务实践—特别是增长营销及用户流......
  • app自动化之adb报错合集
    1、提示这个错误,很多时候说的是adb版本过旧导致的,说的更新一下abd,但是使用SDKManager安装platform-tools(内含adb)选择的是最新的版本,所以不存在adb过旧,只能是其他原因。此时得考虑一下端口被占用的原因。百度了一下最后发现是因为360手机助手占用了对应端口,将360手机助手关闭或是......
  • 如何使用 Bittly 进行基于串口的自动化测试
    串口通信是一种常见的通信方式,广泛用于嵌入式设备、传感器及其他硬件设备的数据交互与控制。通过串口通信,我们能够实时监控设备状态、发送指令并接收反馈。在自动化测试场景中,Bittly提供了一套灵活高效的工具,能够快速创建和管理自动化测试任务,简化复杂的测试流程。同时,Bitt......
  • 数据飞轮实现游戏行业市场主导:自动化营销的新典范
    在现代的数据驱动时代,游戏行业特别依赖于数据分析和数据驱动的决策制定。从数据仓库出发,经过数据中台的发展,最终到达了数据飞轮模式。这一系列的进步显著提高了游戏公司在市场竞争中的敏捷性和效率。本文将深入探讨这一转变如何在游戏行业中实现自动化营销、提供全景客户视图,并有效......
  • 十三 系统架构设计(考点篇)
    1软件架构的概念一个程序和计算系统软件体系结构是指系统的一个或者多个结构。结构中包括软件的构件,构件的外部可见属性以及它们之间的相互关系。体系结构并非可运行软件。确切地说,它是一种表达,使软件工程师能够:(1)分析设计在满足所规定的需求方面的有效性:(2)在......
  • 【java面经】微服务架构速记
    目录由来是什么本质和单体架构的区别适用项目开发框架SpringCloud(流行)DubboDropwizardConsul,etcd&etc(微服务的模块)由来独立系统,SOA服务切换时间长,成本高,不够稳定是什么一套小服务来开发单个应用,每个服务运行在自己的进程中,使用HTTPAPI等轻量级机制通信服务可......