如何从@ pytest.mark.parametrize中的fixture获取确切值
我使用了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_1和create_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
只是为了让你了解你的固定装置会处理什么对象。你可以不使用它。