pytest的Describe风格插件
项目描述
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 的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 39bb05eb90f2497d9ca342ef9a0b7fa5bada7e58505aec33f66d661d631955b7 |
|
MD5 | a48d626f4062bcea8094059bb8daefb1 |
|
BLAKE2b-256 | 61584079baf5a7937159aa59b2f696f8d61c55a6ae4df87bd9ed49e7e130df21 |
pytest_describe-2.2.0-py3-none-any.whl 的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | bd9e2c73acb4b9522a8400823d98f5b6a081667d3bfd7243a8598336896b544d |
|
MD5 | 5f389f04ea46458a897be179f1b551f4 |
|
BLAKE2b-256 | 5d952990d6e3e777be36690700b524d7daf44c9562158d1af6a8f85a6236f22c |