【python自动化】pytest系列(下)

1123 篇文章 45 订阅
858 篇文章 3 订阅

「本章知识点」

  • Pytest之fixture

    • (1)fixture实现前/后置

    • (2)fixture数据传递

    • (3)fixture全局共享机制conftest.py

    • (4)fixture嵌套

Pytest之fixture

「示列代码」

使用装饰器的方式,scope参数是代表指定作用域的

@pytest.fixture(scope='function')
    def test_01(self):
        print("test001")

「源码分析」

def fixture(  # noqa: F811
    fixture_function: Optional[FixtureFunction] = None,
    *,
    scope: "Union[_ScopeName, Callable[[str, Config], _ScopeName]]" = "function",
    params: Optional[Iterable[object]] = None,
    autouse: bool = False,
    ids: Optional[
        Union[Sequence[Optional[object]], Callable[[Any], Optional[object]]]
    ] = None,
    name: Optional[str] = None,
) -> Union[FixtureFunctionMarker, FixtureFunction]:

可以简化为如下:

@pytest.fixture(scope="", params="", autouse="", ids="", name="")

scope:表示的是@pytest.fixtur标记方法的作用域,function(默认),class,module,package/session

params:可迭代参数,支持列表[],元组(),字典列表[{},{},{}],字典元组({}.{},{})

autouse=True:自动执行,默认为False,不会自动执行,需要手动调用

ids:当使用params参数化时,给每一个值设置一个变量名,用的少

name:给被@pytest.fixtur标记的方法取一个别名

scope参数为session:所有测试.py文件执行前执行一次

scope参数为module:每一个测试.py文件执行前都会执行一次conftest文件中的fixture

scope参数为class:每一个测试文件中的测试类执行前都会执行一次conftest文件中的

scope参数为function:所有文件的测试用例执行前都会执行一次conftest文件中的fixture

(1)fixture实现前/后置

四个作用域

1、测试函数 function

2、测试类 class

3、测试模块 module

4、测试会话 session

「默认为function」

源码查看

:param scope:
        The scope for which this fixture is shared; one of ``"function"``
        (default), ``"class"``, ``"module"``, ``"package"`` or ``"session"``.

        This parameter may also be a callable which receives ``(fixture_name, config)``
        as parameters, and must return a ``str`` with one of the values mentioned above.

        See :ref:`dynamic scope` in the docs for more information.

「① 只需要在用例代码的参数中加入前置方法名即可完成前置操作」

示列代码一:

class Test001():

    @pytest.fixture(scope='function')
    def beferFunction(self):
        print("fixture的function")

    @pytest.fixture(scope='class')
    def beferClass(self):
        print("fixture的class")

    @pytest.fixture(scope='module')
    def beferModule(self):
        print("fixture的module")

    def test_04(self,beferFunction,beferClass,beferModule):
        print("测试用例004")

执行结果

============================= test session starts =============================
collecting ... collected 1 item

test_001.py::Test001::test_04 fixture的module
fixture的class
fixture的function
PASSED                                     [100%]测试用例004


============================== 1 passed in 0.03s ==============================

执行顺序:module --> class --> function --> 用例

「类级别的前后置,一定要写到第一个用例上, 写在最后一个上的话,执行时不会检测到有类级别前置,所以不会执行。检测到 有类级别前置,才会执行;」

现在我也找了很多测试的朋友,做了一个分享技术的交流群,共享了很多我们收集的技术文档和视频教程。
如果你不想再体验自学时找不到资源,没人解答问题,坚持几天便放弃的感受
可以加入我们一起交流。而且还有很多在自动化,性能,安全,测试开发等等方面有一定建树的技术大牛
分享他们的经验,还会分享很多直播讲座和技术沙龙
可以免费学习!划重点!开源的!!!
qq群号:691998057【暗号:csdn999】

示列代码二:

「② 使用@pytest.mark.usefixtures("前/后置函数名")」

import pytest

@pytest.fixture(scope="function")
def fixture_fun():
    print("function级别的前置操作")
    yield
    print("function级别的后置操作")


@pytest.mark.usefixtures("fixture_fun")
def test_001():
    print("我是用例1111111")

运行结果

============================= test session starts =============================
collecting ... collected 1 item

test_001.py::test_001 function级别的前置操作
PASSED                                             [100%]我是用例1111111
function级别的后置操作


============================== 1 passed in 0.01s ==============================

「使用yield关键字实现后置操作」

示列代码:

class Test001():
    @pytest.fixture(scope='function')
    def beferFunction(self):
        print("fixture的function前置操作")
        yield
        print("fixture的function后置操作")

    def test_001(self,beferFunction):
        print("测试用例001")

运行结果:

============================= test session starts =============================
collecting ... collected 1 item

test_002.py::Test001::test_001 fixture的function前置操作
PASSED                                    [100%]测试用例001
fixture的function后置操作


============================== 1 passed in 0.01s ==============================

其他级别前后置操作同理。

1、如果希望某个测试类下所有的方法都执行function级别的前后置方法,在测试类前使用@pytest.fixture(scope='function')即可。

2、有多个同类型的scope叠加使用,从下至上依次执行。

(2)fixture数据传递

# 传递
yield 返回值
# 接收
# 以fixture函数名作为用例参数,用例参数接收返回值,可以有多个

示列代码:

import pytest


@pytest.fixture(scope="function")
def func01():
    print("函数级别的前置")
    yield "返回值1",100
    print("函数级别的后置")

@pytest.mark.usefixtures("func01")
def test001(func01): # 参数 func01 = 函数名叫做func01的返回值
    print(f"测试用例test001,接收到的参数为:{func01}") 

运行结果

============================= test session starts =============================
collecting ... collected 1 item

test_fixture前置数据传递.py::test001 函数级别的前置
PASSED                              [100%]测试用例test001,接收到的参数为:('返回值1', 100)
函数级别的后置


============================== 1 passed in 0.06s ==============================

(3)fixture全局共享机制conftest.py

  • 通过「conftest.py」文件实现共享fixture,文件名固定为conftest.py,不可更改

  • 用处:在不同的py文件中使用同一个fixture函数

  • 优先级:就近原则!

  • 共享范围:当前conftest.py所在目录下的所有用例共享,包括子文件夹

  • conftest.py,是可以创建多个在不同的包下,可以层级创建的。

  • conftest.py需要和运行的用例放到同一层,不需要用import导入操作

  • 所有同目录测试文件运行前都会执行conftest.py文件

新建如下目录结构:

conftest.py文件中编写如下代码:

# -*- coding: utf-8 -*-
'''
@Time : 2023/2/15 11:51
@Author : Vincent.xiaozai
@Email : Lvan826199@163.com
@File : conftest.py
'''
__author__ = "梦无矶小仔"

'''
1、放的都是fixture
2、fixture可以对外共享
3、共享范围:
    当前conftest.py所在目录下的所有用例共享,包括子文件夹
4、conftest.py,是可以创建多个在不同的包下,可以层级创建的。
5、优先级:就近原则!
'''

import pytest

@pytest.fixture(scope="function")
def func_fixture():
    print("conftest.py下的func_fixture前置")
    yield
    print("conftest.py下的func_fixture后置")
    
@pytest.fixture(scope="function")
def func_fixture_01():
    print("conftest.py下的func_fixture前置")
    yield
    print("conftest.py下的func_fixture后置")

@pytest.fixture(scope="class")
def class_fixture():
    print("conftest.py下的class_fixture前置")
    yield
    print("conftest.py下的class_fixture后置")

@pytest.fixture(scope="module")
def module_fixture():
    print("conftest.py下的module_fixture前置")
    yield
    print("conftest.py下的module_fixture后置")


@pytest.fixture(scope="function")
def func_fixture_param():
    print("conftest.py下的func_fixture_param前置")
    yield 1, 2, 3, 4, 5
    print("conftest.py下的func_fixture_param后置")

test_002.py文件中直接使用conftest.py文件中定义的fixture方法。

import pytest

@pytest.fixture(scope="function")
def func_fixture():
    print("test_002.py下的func_fixture前置")
    yield
    print("test_002.py下的func_fixture后置")

class Test002():

    def test_aa(self,func_fixture):
        print("----运行了test_aa用例----")

    def test_bb(self,func_fixture_01):
        print("----运行了test_bb用例----")

    def test_cc(self,class_fixture):
        print("----运行了test_cc用例----")

    def test_dd(self,func_fixture_param):
        print(f"----运行了test_dd用例----参数:{func_fixture_param}")

    @pytest.mark.usefixtures("func_fixture")
    def test_ee(self):
        print("----运行了test_ee用例----")

运行结果:

============================= test session starts =============================
collecting ... collected 5 items

test_002.py::Test002::test_aa test_002.py下的func_fixture前置
PASSED                                     [ 20%]----运行了test_aa用例----
test_002.py下的func_fixture后置

test_002.py::Test002::test_bb conftest.py下的func_fixture前置
PASSED                                     [ 40%]----运行了test_bb用例----
conftest.py下的func_fixture后置

test_002.py::Test002::test_cc conftest.py下的class_fixture前置
PASSED                                     [ 60%]----运行了test_cc用例----

test_002.py::Test002::test_dd conftest.py下的func_fixture_param前置
PASSED                                     [ 80%]----运行了test_dd用例----参数:(1, 2, 3, 4, 5)
conftest.py下的func_fixture_param后置

test_002.py::Test002::test_ee test_002.py下的func_fixture前置
PASSED                                     [100%]----运行了test_ee用例----
test_002.py下的func_fixture后置
conftest.py下的class_fixture后置


============================== 5 passed in 0.02s ==============================

我们在两个文件中都有func_fixture的fixture方法,运行发现,test_002.py使用的是自己文件下的,而不是conftest里面的,这很好的说明了一个就近原则。

(4)fixture嵌套

@pytest.fixture
def func1():
    print("func1的前置")
    yield
    print("func1的后置")

我有个需求,就是需要用到func1,但是我要在此基础上新增一些内容。于是乎我造了一个func2

@pytest.fixture
def func2():
    print("fun1的前置")
    print("新增:func2的前置")
    yield
    print("新增:func2的后置")
    print("func1的后置")

这样写会造成大量的代码冗余,有什么办法解决呢?这就需要用到我们继承的理念。

继承func1并在内部执行func1

@pytest.fixture
def func3(func1):
    print("新增:func3的前置")
    yield func1
    print("新增:func3的后置")

运行如下测试用例,输出结果就和调用func2运行一致。

def test001(func3):
    print("我是测试用例001")
    
    ### 运行结果如下 ###
============================= test session starts =============================
collecting ... collected 1 item

test_003_fixture嵌套.py::test001 func1的前置
新增:func3的前置
PASSED                                  [100%]我是测试用例001
新增:func3的后置
func1的后置


============================== 1 passed in 0.01s ==============================

Process finished with exit code 0

下面是配套资料,对于做【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴我走过了最艰难的路程,希望也能帮助到你!

最后: 可以在公众号:程序员小濠 ! 免费领取一份216页软件测试工程师面试宝典文档资料。以及相对应的视频学习教程免费分享!,其中包括了有基础知识、Linux必备、Shell、互联网程序原理、Mysql数据库、抓包工具专题、接口测试工具、测试进阶-Python编程、Web自动化测试、APP自动化测试、接口自动化测试、测试高级持续集成、测试架构开发测试框架、性能测试、安全测试等。

如果我的博客对你有帮助、如果你喜欢我的博客内容,请 “点赞” “评论” “收藏” 一键三连哦!

  • 13
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Python接口自动化测试框架pytest是一种简单易用的工具,用于编写和执行接口测试用例。它具有以下特点和优势。 首先,pytest使用简单,代码易读性高。相比其他测试框架,pytest的语法更加简洁,使用起来更加灵活。它可以方便地编写测试用例、断言和测试数据,使我们能够更快地完成接口测试的编写工作。 其次,pytest提供了丰富的插件和扩展功能。pytest有很多插件可以用来增强其功能和灵活性。例如,pytest-html插件可以生成漂亮的测试报告,pytest-xdist插件可以实现多线程并发执行测试用例,pytest-rerunfailures插件可以重新运行失败的测试用例等。这些插件可以根据需求进行安装和配置,提高测试效率和自动化程度。 第三,pytest支持并行测试执行。多线程并发执行测试用例可以节省大量的测试时间,提高测试效率。pytest-xdist插件是一个很好的选择,它可以实现分布式地在多台计算机上并行执行测试用例,加快测试速度。 此外,pytest还支持测试标记、测试参数化、测试数据驱动、测试用例生成等强大的功能,使得测试用例编写更加灵活和高效。 总之,Python接口自动化测试框架pytest在接口测试中具有简单易用、丰富的插件和扩展功能、支持并行测试执行等优点。它的功能和灵活性使得我们能够更好地进行接口测试,并且提高测试效率和自动化程度。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值