跳至主要内容

pytest的Describe风格插件

项目描述

PyPI version Workflow status

pytest的Describe风格插件

pytest-describe 是一个为 pytest 定制的插件,它允许测试以任意嵌套的 describe-blocks 编写,类似于 RSpec(Ruby)和 Jasmine(JavaScript)。

这个项目的灵感主要来自一个由 Gary Bernhardt 制作的视频:视频链接

安装

猜对了

pip install pytest-describe

用法

当你运行 pytest 时,Pytest 会自动找到并使用此插件。运行 pytest 会显示插件已加载。

$ pytest 
...
plugins: describe-2.2.0
...

现在可以在 describe-blocks 中编写测试。以下是一个测试 Wallet 类的示例。

import pytest


class Wallet:

    def __init__(self, initial_amount=0):
        self.balance = initial_amount

    def spend_cash(self, amount):
        if self.balance < amount:
            raise ValueError(f'Not enough available to spend {amount}')
        self.balance -= amount

    def add_cash(self, amount):
        self.balance += amount
        
        
def describe_wallet():
    
    def describe_start_empty():
        
        @pytest.fixture
        def wallet():
            return Wallet()

        def initial_amount(wallet):
            assert wallet.balance == 0
    
        def add_cash(wallet):
            wallet.add_cash(80)
            assert wallet.balance == 80

        def spend_cash(wallet):
            with pytest.raises(ValueError):
                wallet.spend_cash(10)

    def describe_with_starting_balance():
        
        @pytest.fixture
        def wallet():
            return Wallet(20)

        def initial_amount(wallet):
            assert wallet.balance == 20
    
        def describe_adding():
            
            def add_little_cash(wallet):
                wallet.add_cash(5)
                assert wallet.balance == 25
    
            def add_much_cash(wallet):
                wallet.add_cash(980)
                assert wallet.balance == 1000
                
        def describe_spending():
            
            def spend_cash(wallet):
                wallet.spend_cash(15)
                assert wallet.balance == 5
        
            def spend_too_much_cash(wallet):
                with pytest.raises(ValueError):
                    wallet.spend_cash(25)

describe-blocks 的默认前缀为 describe_,但您可以通过 pytest/python 配置文件中的 describe_prefixes 或命令行选项 --describe-prefixes 进行配置。

例如在你的 pyproject.toml 中:

[tool.pytest.ini_options]
describe_prefixes = ["custom_prefix_"]

在 describe-block 中以 _ 开头的函数不会被收集为测试。这可以用来分组辅助函数。否则,describe-blocks 内部的函数不需要遵循任何特殊的命名约定。

def describe_function():

    def _helper():
        return "something"

    def it_does_something():
        value = _helper()
        ...

为什么要这样做呢?

我发现我的测试往往比生产代码多一个“维度”。生产代码组织成包、模块、类(有时)和函数。我喜欢以相同的方式组织我的测试,但测试对于每个函数都有不同的 cases。这通常会导致每个模块(或类)都有一组测试,每个测试都必须命名一个函数和一个 case。例如:

def test_my_function_with_default_arguments():
def test_my_function_with_some_other_arguments():
def test_my_function_throws_exception():
def test_my_function_handles_exception():
def test_some_other_function_returns_true():
def test_some_other_function_returns_false():

这样做会更好

def describe_my_function():
    def with_default_arguments():
    def with_some_other_arguments():
    def it_throws_exception():
    def it_handles_exception():

def describe_some_other_function():
    def it_returns_true():
    def it_returns_false():

它还有一个额外的优点,即您可以具有适用于每个测试函数组的局部标记和 fixtures。

使用 pytest,可以以类似的方式使用类来组织测试。然而,我认为类很尴尬。我认为类名使用驼峰式命名约定在测试不同 case 的函数时并不合适。此外,每个测试函数都必须接受一个“self”参数,这个参数永远不会使用。

pytest-describe 插件允许您使用 describe-blocks 以更优雅的方式组织测试。

共享行为

如果您使用过 rspec 的共享示例或测试类继承,那么您可能熟悉将相同的测试应用于多个“主题”或“suts”(系统测试对象)的好处。

from pytest import fixture
from pytest_describe import behaves_like

def a_duck():
    def it_quacks(sound):
        assert sound == "quack"

@behaves_like(a_duck)
def describe_something_that_quacks():
    @fixture
    def sound():
        return "quack"

    # the it_quacks test in this describe will pass

@behaves_like(a_duck)
def describe_something_that_barks():
    @fixture
    def sound():
        return "bark"

    # the it_quacks test in this describe will fail (as expected)

包含共享行为的块中定义的 fixtures 优先于共享行为中定义的 fixtures。这条规则仅适用于 fixtures,不适用于其他函数(嵌套 describe-blocks 和测试)。相反,它们都被收集为单独的测试。

项目详情


下载文件

下载您平台上的文件。如果您不确定选择哪个,请了解更多关于 安装软件包 的信息。

源代码分发

pytest-describe-2.2.0.tar.gz (10.9 kB 查看哈希值)

上传时间

构建分发

pytest_describe-2.2.0-py3-none-any.whl (6.9 kB 查看哈希值)

上传时间 Python 3

由以下支持