[跟着官方文档学pytest][四][学习笔记]

举报
John2021 发表于 2022/05/03 16:41:27 2022/05/03
【摘要】 1.关于fixturespytest fixtures被设计为显式,模块化和可扩展的。 1.1.什么是fixtures在测试中,fixtures为测试提供了定义、可靠和一致的上下文。这可能包括环境(例如,配置了已知参数的数据库)或内容(例如数据集)。Fixture定义了构成测试排列阶段的步骤和数据(参照Anatomy of a test)。在pytest中,它们是你定义的用于此目的的函数。...

1.关于fixtures

pytest fixtures被设计为显式,模块化和可扩展的。

1.1.什么是fixtures

在测试中,fixtures为测试提供了定义、可靠和一致的上下文。这可能包括环境(例如,配置了已知参数的数据库)或内容(例如数据集)。
Fixture定义了构成测试排列阶段的步骤和数据(参照Anatomy of a test)。在pytest中,它们是你定义的用于此目的的函数。它们可用于定义测试的行为阶段;这是设计更复杂测试的强大技术。
由于fixtures设置的服务、状态或其他操作环境由测试函数通过参数访问。对于测试函数使用的每个fixture,测试函数的定义中通常都有一个参数(以fixture命名)。
我们可以告诉pytest,一个特定的功能是一个用@pytest.fixture修饰的。下面是一个简单例子:

import pytest


class Fruit:
    def __init__(self, name):
        self.name = name

    def __eq__(self, other):
        return self.name == other.name


@pytest.fixture
def my_fruit():
    return Fruit("apple")


@pytest.fixture
def fruit_basket(my_fruit):
    return [Fruit("banana"), my_fruit]


def test_my_fruit_in_basket(my_fruit, fruit_basket):
    assert my_fruit in fruit_basket

测试也不必局限于单个fixture。可以根据需要依赖任意数量的固定fixtures,并且fixtures可以使用其他fixtures。这就是pytest的fixture系统真正亮眼的地方。

1.2.改进xUnit-style的setup/teardown功能

fixtures对经典xUnit-style的setup/teardown功能有如下改进:

  • fixtures据偶显示名称,并通过从测试函数,模块,类或整个项目中声明它们使用来激活。
  • fixtures以模块化方式实现,因为每个fixtures名称都会触发一个fixture功能,这个fixture功能也可以使用其他fixtures。
  • fixture管理从简单的单元扩展到复杂的功能测试,允许根据配置和组件选项参数化fixtures和测试,或跨功能、类、模块或整个测试会话范围重用fixtures。
  • 无论使用多少fixtures,teardown逻辑可以轻松安全地管理,而无需手动自动仔细处理错误或微观管理添加清理步骤的顺序。

1.3.Fixture错误

pytest尽最大努力将给定测试的所有fixtures按线性顺序排序,以便可以看到哪个fixture先发生。如果较早的fixture有问题引发异常,pytest将停止执行该测试的fixtures,并将测试标记为错误。
但是当测试被标记为错误时,并不意味着测试失败。只是意味着无法尝试测试,因为它所依赖的事物之一存在问题。
这就是为什么为给定测试删除尽可能多的不必要的依赖项是个好主意原因之一。这样不相关事物中的问题就不会导致我们对可能存在或可能没有问题的内容有不完整的了解。
以下示例帮我们理解fixture

import pytest


@pytest.fixture
def order():
    return []


@pytest.fixture
def append_first(order):
    order.append(1)


@pytest.fixture
def append_second(order, append_first):
    order.extend([2])


@pytest.fixture(autouse=True)
def append_third(order, append_second):
    order += [3]


def test_order(order):
    assert order == [1, 2, 3]

如果,无论出于何种原因,order.append(1)有一个错误并且引发了异常,将无法知道order.extend([2])order+=[3]是否会有问题。在append_first抛出异常后,pytest不会再为test_order运行任何fixtures,甚至不会尝试运行test_order本身。唯一会运行的东西将是orderappend_first
为了引发异常将order.append(1)改为order.append(),会发生如下图异常:

1.4.分享测试数据

如果要使文件中的测试数据可用于测试,一个好方法是将这些数据加载到fixtures中以供测试使用。这利用了pytest的自动缓存机制。
另一种好方法是在tests文件夹中添加数据文件。还有一些社区插件可以帮助管理测试的这一方面,例如pytest-datadir和pytest-datafiles。

1.5.Fixture清理的说明

pytest不对SIGTERM和SIGQUIT信号进行任何特殊处理(SIGINT由Python运行时通过键盘中断自然处理),因此管理外部资源的fixtures在Python进程终止时(通过这些信号)需要清除,可能会泄漏资源。
pytest不处理这些信号来执行fixture清理的原因是信号处理程序是全局的,更改它们可能会干扰正在执行的代码。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。