Services Blog Français

pytest superfixture design pattern

| by jpic | python pytest

pytest is an awsome Python Test framework which starts over from a clean slate instead of following the xUnit pattern.

Instead of:

class YourTestSuite(unittest.TestCase):
    def setUp(self):
        self.some_stuff = YourThing()

    def test_delete(self):

We do:

def some_stuff():
    return YourThing()

def test_delete(some_stuff):
    assert not some_stuff.exists()

A couple of advantages are worth noting:

  • the fixture is not created in every test
  • we also win one indentation level which is pretty cool!

However, what about complex code where we test the glue between over a dozen of fixtures?

def test_delete(stuff, client, timestamp, bottle_contract, redeem_contract, blockchain, account):
    # ...

We end up with a lot of fixtures in the signature. Hence the invention of the superfixture pattern. It’s just a fixture class with cached properties that will be created for the time of the test as needed, it’s basically pure python, leveraging the awesome functools.cached_property decorator:

class Fixture:
    def stuff(self):
        return Stuff()

    def blockchain(self):
        return Blockchain.objects.create(name='ethlocal')

    def account(self):
        return self.blockchain.account_set.create()

    def client(self):
        client = APIClient()
        return client

    def bottle_contract(self):
        return BottleContract.objects.create(

    def redeem_contract(self):
        return RedeemContract.objects.create(

Then, you can use it as such in your tests:

def fixture():
    return Fixture()

def test_something(fixture):
    response =
    assert fixture.redeem_contract.redeemed

You can even pass through fixtures from plugins, ie:

def fixture(mocker):
    return Fixture(mocker)

But, if you just want an object to be created, you need to call the property, in this case, maybe add a comment so that it doesn’t look like a mistake:

def test_something(fixture):
    fixture.redeem_contract  # ensure redeem contract creation prior to test
    # stuff

That’s it! Work smart, not hard ;)

Work smart, not hard

They trust us