I have several pytest fixtures:
@pytest.fixture
def articles_new(category):
article_new_1 = ArticleFactory.create(category=category["category_1"], status=ArticleStatusChoices.NEW)
article_new_2 = ArticleFactory.create(category=category["category_2"], status=ArticleStatusChoices.NEW)
return {"article_new_1": article_new_1, "article_new_2": article_new_2}
@pytest.fixture
def articles_published_with_readers(category):
article_published_with_readers_1 = ArticleFactory.create(
category=category["category_2"],
readers=ArticleRoleTypesChoices.EMPLOYEE,
status=ArticleStatusChoices.PUBLISHED,
)
return {"article_published_with_readers_1": article_published_with_readers_1}
@pytest.fixture
def category(product):
category_1 = CategoryFactory.create(product=product["product_1"])
category_2 = CategoryFactory.create(product=product["product_2"])
return {"category_1": category_1, "category_2": category_2}
@pytest.fixture
def product():
product_1 = ProductFactory.create()
product_2 = ProductFactory.create()
return {"product_1": product_1, "product_2": product_2}
I try to refactor such test:
def test_articles(self, client, user):
client.force_login(user)
res = client.get(reverse("get_article", kwargs={"article_guid": article_new_1.guid}))
assert res.status_code == 200
res = client.get(reverse("get_article", kwargs={"article_guid": article_published_with_readers_1.guid}))
assert res.status_code == 403
into something like that:
@pytest.mark.parametrize(
"article, expected",
[
......
],
)
def test_articles(self, client, user, article, expected):
client.force_login(user)
res = client.get(reverse("get_article", kwargs={"article_guid": article.guid}))
assert res.status_code == expected
How can this problem be solved?
Note: article_new_1 and article_published_with_readers_1 have different categories.
Here is one way to solve this:
Output:
Notes
Instead of passing into the test the actual article, I passed in
article_type: "new" or "published". In the test, I will use this article type to determine which type of article to create.create_new_article()andpublish_article()are not fixtures, they are just normal functionsI mocked those fixtures/functions/classes which I don't have access to
Instead of
I use
This allow the flexibility of given each parametrized case a name such as "success case" or "failed case"
This solution is a bit messy with a big
ifblock used to create the article instead of passing the article directly into the test, but it is simple and easy to understand.