首页 > 其他分享 >软件测试/测试开发全日制|Pytest中yield的用法详解

软件测试/测试开发全日制|Pytest中yield的用法详解

时间:2024-01-12 15:02:08浏览次数:33  
标签:fixture pytest yield print Pytest test 执行 软件测试

软件测试/测试开发全日制|Pytest中yield的用法详解_脏数据

前言

在之前的介绍中,我们已经介绍了fixture的简单用法,但其实fixture还提供了两种非常优雅高效的写法,来完成测试执行前的处理操作与执行后的处理操作,即使用yieldaddfinalizer来实现。本文我们将介绍使用yield来实现操作。

yield

在fixture中的关键字yield主要有两个作用:

  • yield代替return进行参数的传递
  • 起到代码的分割作用,yield之前的代码为setup的作用,yield之后的代码为teardown的作用

yield 与 return

在 pytest 的fixture函数中可以使用yield代替return进行返回,示例如下:

import pytest
 
@pytest.fixture(autouse=True)
def fixture_one():
    print("执行fixture_one")
    yield 1
    
def test_e(fixture_one):
    print("执行test_e")
    print(fixture_one)
    assert fixture_one == 1
 
 
if __name__ == '__main__':
    pytest.main(["-s"])

----------------
执行结果如下:
test_case_4.py::test_e 
执行fixture_one
PASSED                                            [100%]执行test_e
1
 
 
============================== 1 passed in 0.12s ==============================

从运行结果我们能看到fixture_one会返回1并传递给test_e,与return的作用完全一致。但如果仅仅只是这样使用的话,毫无意义,因为使用return足够了。所以,在实际的使用过程中我们一般会在yield后面加上teardown的代码。

yield 与 teardown

yield不进行参数传递

对于不需要在前置操作中返回数据的 fixture 函数,加入yield,那么yield之前的代码为用例执行之前的操作(即setup),yield之后的代码为用例执行之后的操作(即teardown)。示例如下:

import pytest
 
@pytest.fixture()
def fixture_demo():
    # setup
    print("\n连接数据库")
    yield
    # teardown
    print("清空脏数据")
 
def test_case(fixture_demo):
    print("执行test_case")
    assert True
 
 
if __name__ == '__main__':
    pytest.main(["-s"])

--------------------
运行结果如下:
============================= test session starts =============================
collecting ... collected 1 item

test_demo01.py::test_case 
连接数据库
PASSED                                         [100%]执行test_case
清空脏数据


============================== 1 passed in 0.02s ==============================

从结果中我们可以看出来,先执行了setup部分,再执行测试用例,最后执行teardown部分。

yield进行参数传递

yield可以将参数传递给测试用例。

假设有这样一个场景,需要用到接口1的返回参数作为接口2的请求参数,即接口2依赖接口1,我们需要写一条测试用例对接口2进行测试,这个时候可以将接口1的请求写在前置中,如果是unittest框架则代码如下:

import unittest
import requests
 
class TestDemo(unittest.TestCase):
 
    def setup(self):
        print("请求接口1")
        self.res_1 = requests.get(url=url_1, params=params_1)
 
    def test_api_2(self):
        print("验证接口2")
        # 将接口1的返回值self.res_1作为请求参数,请求接口2
        res = requests.post(url=url_2, data=self.res_1)
        # 断言
        self.assertEqual(res, "接口2预期的返回结果")
 
    def teardown(self):
        print("清空脏数据")

pytest框架中使用fixture+yield则可编写如下:

@pytest.fixture()
def get_api_1_result():
    # setup
    res_1 = requests.get(url=url_1, params=params_1)
    yield res_1
    # teardown
    print("清空脏数据")
    
 
def test_api_2(get_api_1_result):
    print("验证接口2")
    # 将接口1的返回值res_1作为请求参数,请求接口2
    res = requests.post(url=url_2, data=get_api_1_result)
    # 断言
    assert res == "接口2预期的返回结果"

其中,fixture 会先通过yield返回res_1,并传入测试用例test_api_2中,test_api_2运行完成后再去执行yield后面的代码,即执行print("清空脏数据")

通过以上对比unittestsetupteardown以及参数的传递,我们就能很直观的看出pytestyield的使用方式,此处代码仅为示例。

yield 的执行顺序

有时候我们会遇到一个fixture函数调用另一个或多个fixture函数,且这些函数中可能含有yield,我们先看示例,代码如下:

import pytest
 
@pytest.fixture
def fixture_1():
    print("\n执行fixture_1")
    yield 1
    print("\n执行fixture_1的teardown代码")
 
@pytest.fixture
def fixture_2(fixture_1):
    print("\n执行fixture_2")
    yield 2
    print("\n执行fixture_2的teardown代码")
 
@pytest.fixture
def fixture_add(fixture_1, fixture_2):
    print("\n执行fixture_add")
    result = fixture_1 + fixture_2
    yield result
    print("\n执行fixture_add的teardown代码")
 
    
def test_demo(fixture_add):
    print("\n执行测试函数test_demo")
    assert fixture_add == 3
 
 
if __name__ == '__main__':
    pytest.main(["-s"])

-----------
执行结果如下:
collecting ... collected 1 item
 
test_case_4.py::test_demo 
执行fixture_1
 
执行fixture_2
 
执行fixture_add
PASSED                                         [100%]
执行测试函数test_demo
 
执行fixture_add的teardown代码
 
执行fixture_2的teardown代码
 
执行fixture_1的teardown代码
 
 
============================== 1 passed in 0.12s ==============================

从结果可以看出:

test_demo·测试函数执行之前:先执行了 fixture_1,再执行fixture_2,最后执行fixture_add,注意此时都是执行yield之前的的代码;

test_demo 测试函数执行之后:先执行了 fixture_add,再执行fixture_2,最后执行fixture_1,注意此时都是执行yield之后的的代码。

因此,当一个fixture函数调用另一个或多个fixture函数,且fixture函数中含有yield时,被测试函数调用时有如下执行顺序:

  • 测试函数执行之前,pytest会根据fixture函数之间的线性关系顺序调用,即依次执行yield之前的代码。
  • 而测试函数执行结束后,pytest会根据之前的顺序反方向执行fixture函数中yield之后的代码。

总结

总的来说,yield 关键字为 Pytest fixture 提供了一种优雅的方式来处理资源管理、测试环境设置和清理工作,使得测试代码更加健壮和可靠。希望本文能够帮到大家!


标签:fixture,pytest,yield,print,Pytest,test,执行,软件测试
From: https://blog.51cto.com/u_15640304/9217815

相关文章

  • 软件测试/测试开发全日制|Pytest conftest.py配置文件如何使用?
    前言我们知道在python中要想实现数据的共享,可以定义一个“全局变量”,在另一个文件中使用的时候通过先导入,再使用的方式来访问。pytest中定义个conftest.py来实现数据,参数,方法、函数的共享。本文就给大家介绍一下conftest.py的用法。conftest.pyconftest.py文件是pytest的一个特殊文......
  • 软件测试/测试开发全日制|Pytest测试框架Fixture作用域详解
    前言Pytest的fixtrue是存在作用域的,比如作用域为函数级别,那么没执行一条用例,就会重新执行一次fixtrue,如果是类级别,那么多个类执行时会在去执行fixture。fixture的作用域有5个,分别是:function,class,module,package,session。有了这些作用域我们可以不用重复的去执行fixture,从......
  • 软件测试需求分析,先搞清楚这几条
    需求规格说明书的检查,又叫黑盒静态测试,即不知道代码,又不执行代码,在什么都不了解的情况下,进行测试。一、检查要点:1、正确性:对照原始需求,需求是一定,不会产生误解的2、必要性:需求不能多,也不能少3、优先级:划分各个需求项,风险评估中的重要一点,有可能会舍弃优先级较低的需求4、明确性:不能......
  • 软件测试/测试开发全日制|Pyest结合json实现数据驱动测试
    前言数据驱动测试是提高代码覆盖率和可靠性的重要方法。结合pytest和JSON(JavaScript对象表示)文件可以轻松实现数据驱动测试。和CSV文件类似,Python读取json文件也不需要借助其他的第三方库,因此我们不需要进行额外的环境安装。下面是如何使用pytest和JSON文件进行数据驱动测试的步骤......
  • 软件测试/测试开发全日制|Pytest测试框架fixture作为参数使用
    前言测试用例参数化的时候,使用pytest.mark.parametrize()参数化传测试数据,如果我们想引用前面不同fixture返回的数据当测试用例的入参。这个时候我们就可以用fixture参数化prams来间接解决这个问题,本文就来给大家介绍一下如何使用fixture来实现参数化。使用案例我们需要在测试......
  • 软件测试/测试开发全日制|Pytest结合CSV实现测试的数据驱动
    前言数据驱动测试是一种有效的测试方法,可以使用不同的输入数据运行相同的测试用例。结合pytest和CSV文件可以方便地实现数据驱动测试,相比于yaml以及Excel,使用CSV实现数据驱动不需要借助其他的第三方库,可以直接使用Python读取数据。在这篇文章中,我们将介绍如何使用pytest和CSV实现数......
  • 软件测试/测试开发全日制培训|Pytest的异常处理
    前言在断言一些代码块或者函数时会引发意料之中的异常或者其他失败的异常导致程序无法运行时,使用raises捕获匹配到的异常可以让代码继续运行。Python的异常处理:try...except...else...finally...,示例如下:try:print("正常的操作")exceptTypeError:print("发生TypeError......
  • 软件测试/测试开发全日制|Pytest结合yaml实现数据驱动
    前言我们之前介绍过pytest的参数化,我们使用了@pytest.mark.parametrize(argnames,argvalues)来实现批量传送参数的目的,但是我们不进行数据驱动的话,我们一旦对数据进行变更,就需要在代码里对我们的参数进行逐一的修改,这对我们来说,是额外增加的工作量,而通过专门存储数据的文件来实现......
  • 软件测试/测试开发全日制|Pytest结合Excel实现数据驱动
    前言数据驱动测试是一种有效的测试方法,可以使用不同的输入数据运行相同的测试用例。结合pytest和Excel表格可以方便地实现数据驱动测试。在这篇文章中,我们将介绍如何使用pytest和Excel实现数据驱动测试。环境准备在实现Excel的数据驱动之前,我们首先要安装Python操作excel的第三方库......
  • 软件测试分析报告
    ......