4

我正在使用 Pytest 编写一些单元测试,并遇到了两种参数化测试输入的方法。一种是使用参数化夹具,另一种是使用pytest.mark.parametrize方法。

我的两个例子是:

# method 1
def tokens():
    yield from ["+", "*", "?"]

@pytest.mark.parametrize("token", tokens())
def test_stuff(token):
    assert stuff

# method 2
@pytest.fixture(params=["+", "*", "?"])
def token(request):
    return request.param

def test_stuff(token):
    assert stuff

据我所知,两者都有不同的优点和缺点:

方法一

优点

  • 支持多种参数
  • 支持惰性求值

缺点

  • 用于多种测试方法时的样板代码更多
  • 需要对使用的每个方法进行显式参数映射,即使参数名称相同

方法二

优点

  • 更少的样板代码

缺点

  • 只允许将单个参数传递给单元测试

我还是 PyTest 的新手,所以也许有一种方法可以解决我上面列出的每种方法的缺点,但考虑到那些我一直很难决定使用哪个方法。我猜想做我想做的事情的预期方法是使用@pytest.mark.parametrize,但是当通过使用夹具仅传递具有较少样板代码的单个参数时似乎是一个很大的优势。谁能告诉我不这样做的理由还是这是一个完全有效的用例?

4

1 回答 1

3

正如pk786在他的评论中提到的那样,您应该使用夹具“......如果您有一些东西要为测试设置和拆卸,或者使用(该)相同的数据集进行多个测试,那么请使用夹具”。

例如,您可能想要加载在不同测试函数中测试的多个数据集。使用夹具允许您只加载这些数据集一次并在测试函数之间共享它们。您可以使用params参数 of@pytest.fixture来加载和缓存每个数据集。然后,使用这些夹具的测试函数将针对每个加载的数据集运行。在代码中,这可能类似于:

import json

import pytest


test_files = ["test_file1.json", "test_file2.json"]


@pytest.fixture(params=test_files)
def example_data(request):
    with open(request.param, "r") as f:
        data = json.load(f)
    return data


def test_function1(example_data):
    # run test with example data.
    # this test will be run once for each file in the list `test_files` above.
    ...


def test_function2(example_data):
    # run a different test with example data.
    # this test will be run once for each file in the list `test_files` above.
    # this test takes advantage of automatic caching mechanisms of fixtures...
    # ...so that data is not loaded again.
    ...   

或者,正如pk786所述,“如果您只使用一组数据一次,那么 @pytest.mark.parametrize 应该是方法”。

此声明适用于您提供的示例,因为您没有在需要跨测试共享的夹具中执行任何设置。在这种情况下,即使您在多个测试中使用“令牌”,我也会考虑使用装饰每个函数,@pytest.mark.parameterize因为我相信这种方法更明确地说明了您的意图,并且对于其他阅读您的代码的人来说更容易理解。这看起来像这样:

...

def tokens():
    yield from ["+", "*", "?"]


@pytest.mark.parametrize("token", tokens())
def test_stuff(token):
    assert stuff


@pytest.mark.parametrize("token", tokens())
def test_other_stuff(token)
    assert other_stuff
于 2020-03-10T07:08:00.973 回答