[TIP] Pytest share fixture data across the class methods

Arup Rakshit ar at zeit.io
Wed Jun 26 03:40:02 PDT 2019


Hi,

I am using pytest to test my flask end points. I have grouped tests related to all unauthenticated access in a class as you see below:

@pytest.mark.usefixtures("client_class")
class TestUnauthorizedRecipesAcces:
    def test_update_a_recipe(self, create_recipe_record):
        recipe = create_recipe_record(
            {
                "cook": "9 min",
                "inactive": "20 min",
                "level": "Easy",
                "prep": "5 min",
                "title": "Grilled Salmon I",
                "total": "34 min",
                "yields": "6 servings",
            }
        )
        assert (
            self.client.put(
                url_for("recipes.recipes_api", _method="PUT", id=recipe.id),
                json={"inactive": "10 min", "level": "easy"},
            ).status_code
            == 401
        )

    def test_delete_a_recipe(self, create_recipe_record):
        recipe = create_recipe_record(
            {
                "cook": "9 min",
                "inactive": "20 min",
                "level": "Easy",
                "prep": "5 min",
                "title": "Grilled Salmon I",
                "total": "34 min",
                "yields": "6 servings",
            }
        )

        assert (
            self.client.delete(
                url_for("recipes.recipes_api", _method="DELETE", id=recipe.id)
            ).status_code
            == 401
        )

    def test_fetch_a_recipe(self, create_recipe_record):
        recipe = create_recipe_record(
            {
                "cook": "9 min",
                "inactive": "20 min",
                "level": "Easy",
                "prep": "5 min",
                "title": "Grilled Salmon I",
                "total": "34 min",
                "yields": "6 servings",
            }
        )

        assert (
            self.client.get(
                url_for("recipes.recipes_api", _method="GET", id=recipe.id)
            ).status_code
            == 401
        )

    def test_attach_a_category_to_a_recipe(
        self, create_recipe_record, create_category_record
    ):
        recipe = create_recipe_record(
            {
                "cook": "45 min",
                "inactive": "",
                "level": "",
                "prep": "30 min",
                "title": "Grilled Salmon II",
                "total": "1 hr 15 min",
                "yields": "4 servings",
            }
        )

        category = create_category_record({"title": "Grilled Chicken"})

        assert (
            self.client.post(
                url_for(
                    "recipe_categories.recipe_categories_api",
                    _method="POST",
                    recipe_id=recipe.id,
                ),
                json={"id": category.id},
            ).status_code
            == 401
        )

    def test_remove_a_category_from_a_recipe(
        self, create_recipe_record, create_category_record
    ):
        recipe = create_recipe_record(
            {
                "cook": "45 min",
                "inactive": "",
                "level": "",
                "prep": "30 min",
                "title": "Grilled Salmon II",
                "total": "1 hr 15 min",
                "yields": "4 servings",
            }
        )

        category = create_category_record({"title": "Grilled Chicken"})
        recipe.add_category(category.id)

        assert (
            self.client.delete(
                url_for(
                    "recipe_categories.recipe_categories_api",
                    _method="DELETE",
                    recipe_id=recipe.id,
                    id=category.id,
                )
            ).status_code
            == 401
        )

Those test data I created to build urls, other than that there are no used of category, recipe records in this group. I was wondering if pytest can help to share the data across all the methods instead of creating them everytime in each method as I did above. Can you suggest me some tricks? I am looking for something like:

@pytest.mark.usefixtures("client_class")
class TestUnauthorizedRecipesAcces:
    # ....

    def test_remove_a_category_from_a_recipe(self):
        assert (
            self.client.delete(
                url_for(
                    "recipe_categories.recipe_categories_api",
                    _method="DELETE",
                    recipe_id=self.recipe.id,
                    id=self.category.id,
                )
            ).status_code
            == 401
        )

How can I achieve this. Fixtures  create_recipe_record, create_category_record are created in contest.py file as a function scope (
https://gitlab.com/aruprakshit/flask_awesome_recipes/blob/master/tests/conftest.py) . The tests can be seen here https://gitlab.com/aruprakshit/flask_awesome_recipes/blob/master/tests/test_recipes.py#L253
 .

Please give me some directions.


Thanks,

Arup Rakshit
ar at zeit.io






More information about the testing-in-python mailing list