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

简介: 软件测试/测试开发全日制|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 提供了一种优雅的方式来处理资源管理、测试环境设置和清理工作,使得测试代码更加健壮和可靠。希望本文能够帮到大家!

相关文章
|
1天前
|
机器学习/深度学习 前端开发 测试技术
探索软件测试中的自动化测试框架选择与优化策略####
本文深入探讨了在当前软件开发生命周期中,自动化测试框架的选择对于提升测试效率、保障产品质量的重要性。通过分析市场上主流的自动化测试工具,如Selenium、Appium、Jest等,结合具体项目需求,提出了一套系统化的选型与优化策略。文章首先概述了自动化测试的基本原理及其在现代软件开发中的角色变迁,随后详细对比了各主流框架的功能特点、适用场景及优缺点,最后基于实际案例,阐述了如何根据项目特性量身定制自动化测试解决方案,并给出了持续集成/持续部署(CI/CD)环境下的最佳实践建议。 --- ####
|
5天前
|
测试技术 开发者 UED
探索软件测试的深度:从单元测试到自动化测试
【10月更文挑战第30天】在软件开发的世界中,测试是确保产品质量和用户满意度的关键步骤。本文将深入探讨软件测试的不同层次,从基本的单元测试到复杂的自动化测试,揭示它们如何共同构建一个坚实的质量保证体系。我们将通过实际代码示例,展示如何在开发过程中实施有效的测试策略,以确保软件的稳定性和可靠性。无论你是新手还是经验丰富的开发者,这篇文章都将为你提供宝贵的见解和实用技巧。
|
3天前
|
jenkins 测试技术 持续交付
软件测试中的自动化测试策略
在当今快速发展的软件行业中,自动化测试已成为确保软件质量和效率的关键工具。本文将探讨自动化测试的重要性、实施策略以及面临的挑战,旨在为软件开发团队提供实用的指导和建议。
|
27天前
|
测试技术
自动化测试项目学习笔记(五):Pytest结合allure生成测试报告以及重构项目
本文介绍了如何使用Pytest和Allure生成自动化测试报告。通过安装allure-pytest和配置环境,可以生成包含用例描述、步骤、等级等详细信息的美观报告。文章还提供了代码示例和运行指南,以及重构项目时的注意事项。
129 1
自动化测试项目学习笔记(五):Pytest结合allure生成测试报告以及重构项目
|
12天前
|
测试技术
探索软件测试中的“思维侧翼”——如何以创新思维引领测试策略###
本文旨在探讨软件测试领域中,如何通过培养与运用创新思维,提升测试策略的有效性与效率。不同于传统的技术解析或理论阐述,本文将以“思维侧翼”为喻,启发读者从不同维度审视软件测试,寻找突破常规的思路与方法。我们相信,在快速迭代的软件开发周期中,灵活多变且富有创造力的测试思维,是发现潜在缺陷、保障产品质量的关键。 ###
|
13天前
|
测试技术 定位技术 UED
软件测试的艺术:探索性测试的深度与广度
【10月更文挑战第22天】在软件开发的广阔舞台上,测试扮演着不可或缺的角色。本文将带领读者深入理解探索性测试(Exploratory Testing)的精髓,揭示其在现代软件质量保证中的价值。我们将通过实际案例、生动比喻和具体步骤,展现如何像艺术家一样进行软件测试,确保产品质量的同时,提升测试的效率和乐趣。文章不仅适合初学者建立测试基础,也能帮助资深测试人员深化对探索性测试的理解和应用。
|
11天前
|
监控 安全 jenkins
探索软件测试的奥秘:自动化测试框架的搭建与实践
【10月更文挑战第24天】在软件开发的海洋里,测试是确保航行安全的灯塔。本文将带领读者揭开软件测试的神秘面纱,深入探讨如何从零开始搭建一个自动化测试框架,并配以代码示例。我们将一起航行在自动化测试的浪潮之上,体验从理论到实践的转变,最终达到提高测试效率和质量的彼岸。
|
3天前
|
测试技术 持续交付
软件测试中的自动化测试策略与最佳实践
【10月更文挑战第31天】 在当今快速迭代的软件开发环境中,自动化测试成为确保软件质量和加速产品上市的关键。本文探讨了自动化测试的重要性、实施策略以及一些最佳实践。通过分析不同类型的自动化测试工具和框架,本文旨在为软件开发团队提供一套实用的指导方案,以提高测试效率和质量。
|
27天前
|
测试技术 Python
自动化测试项目学习笔记(四):Pytest介绍和使用
本文是关于自动化测试框架Pytest的介绍和使用。Pytest是一个功能丰富的Python测试工具,支持参数化、多种测试类型,并拥有众多第三方插件。文章讲解了Pytest的编写规则、命令行参数、执行测试、参数化处理以及如何使用fixture实现测试用例间的调用。此外,还提供了pytest.ini配置文件示例。
19 2
|
17天前
|
测试技术 开发者
探索软件测试中的自动化测试框架
在软件开发的世界中,质量是至关重要的。为了确保软件产品的质量,软件测试扮演着不可或缺的角色。本文将深入探讨自动化测试框架的概念、重要性以及如何有效地实施它们来提高软件测试的效率和效果。我们将从自动化测试的基本概念开始,逐步深入到不同类型的自动化测试工具和框架,最后探讨如何在实际项目中选择合适的自动化测试策略。