如何从@ pytest.mark.parametrize中的fixture获取确切值

1 投票
1 回答
60 浏览
提问于 2025-04-14 17:34

我使用了pytest fixture,它返回一个对象{"article_new_1": article_new_1, "article_new_2": article_new_2}

@pytest.fixture
def create_articles_new(create_categories):
    article_new_1 = ArticleFactory.create(category=create_categories["category_1"], status=ArticleStatusChoices.NEW)
    article_new_2 = ArticleFactory.create(category=create_categories["category_2"], status=ArticleStatusChoices.NEW)
    return {"article_new_1": article_new_1, "article_new_2": article_new_2}

我想用这个fixture来给一个测试添加参数。我希望把这个fixture里的两个文章放到@pytest.mark.parametrize里。

@pytest.mark.parametrize(
    "article,expected",
        [
            ('create_articles_new.article_new_1', 200),
            ('create_articles_new.article_new_2', 403),
        ],
)
def test_articles(client, article, expected):
    res = client.get(reverse("get_article", kwargs={"article_guid": article.guid}))
    assert res.status_code == expected

问题:我应该把create_articles_new.article_new_1create_articles_new.article_new_2替换成什么呢?

1 个回答

1

要让一个固定装置(fixture)创建参数化,你需要在调用时声明 indirect=True。不过,这样的话,你就不能把 expected 当作一个单独的测试函数参数了。相反,article 会是一个 tuple,里面包含了 Article 对象(我猜 ArticleFactory 是用来创建 Article 的)和预期的结果:

import pytest
from _pytest.fixtures import SubRequest


@pytest.fixture()
def article(create_categories, request: SubRequest) -> tuple[Article, int]:
    return (
        ArticleFactory.create(
            category=create_categories[request.param[0]],
            status=ArticleStatusChoices.NEW
        ),
        request.param[1],
    )


@pytest.mark.parametrize(
    "article",
    [
        ("category_1", 200),
        ("category_2", 403),
    ],
    indirect=True,
)
def test_articles(client, article: tuple[Article, int]) -> None:
    res = client.get(
        reverse("get_article", kwargs={"article_guid": article[0].guid})
    )
    assert res.status_code == article[1]

注意事项

  • 固定装置可以通过 request 固定装置和它的 param 属性来访问传入的参数化参数。
  • article 固定装置不一定要返回一个元组。你可以让它返回一个字典、数据类,或者任何你觉得更合适的东西。
  • SubRequest 只是为了让你了解你的固定装置会处理什么对象。你可以不使用它。

撰写回答