Lucky1234
Lucky1234

Reputation: 125

How to organize tests in a class in Pytest?

According to "https://docs.pytest.org/en/stable/getting-started.html" in Pytest when grouping tests inside classes is that each test has a unique instance of the class. Having each test share the same class instance would be very detrimental to test isolation and would promote poor test practices.What does that mean ? This is outlined below: content of test_class_demo.

class TestClassDemoInstance:
    def test_one(self):
        assert 0

    def test_two(self):
        assert 0

Upvotes: 1

Views: 3674

Answers (2)

Marco.S
Marco.S

Reputation: 433

Just to add to Thomas answer, please be aware that currently there is an error in the documentation you mentioned. As described in this open issue on pytest Github, in what is shown below the explanation, both tests are demonstrated to share the same instance of the class, at 0xdeadbeef. This seems to demonstrate the opposite of what is stated (that the instances are not the same).

Upvotes: 2

Thomas
Thomas

Reputation: 181715

Imagine you are testing a user account system, where you can create users and change passwords. You need to have a user before you can change its password, and you don't want to repeat yourself, so you could naively structure the test like this:

class TestUserService:
    def test_create_user(self):
        # Store user_id on self to reuse it in subsequent tests.
        self.user_id = UserService.create_user("timmy")
        assert UserService.get_user_id("timmy") == self.user_id

    def test_set_password(self):
        # Set the password of the user we created in the previous test.
        UserService.set_password(self.user_id, "hunter2")
        assert UserService.is_password_valid(self.user_id, "hunter2")

But by using self to pass data from one test case to the next, you have created several problems:

  1. The tests must be run in this order. First test_create_user, then test_set_password.
  2. All tests must be run. You can't re-run just test_set_password independently.
  3. All previous tests must pass. If test_create_user fails, we can no longer meaningfully run test_set_password.
  4. Tests can no longer be run in parallel.

So to prevent this kind of design, pytest wisely decided that each test gets a brand new instance of the test class.

Upvotes: 5

Related Questions