Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pytest fixture: setup, teardown and code running between each test

I am trying to use pytest to test a module I am writing. The module is a wrapper of a process with a LONG startup time. I, therefore, want to make sure I have a proper setup/teardown logic to make sure the initialization does not happen more than once.

My current code looks like this:

import pytest
import leelaZeroWrapper

@pytest.fixture(scope='module')
def leela(request):
    leela = leelaZeroWrapper.LeelaWrapper()
    def quit():
        leela.quit()
    request.addfinalizer(quit)
    return leela

def test_single_play(leela):
    leela.reset()
    result = leela.play('b', 'a11')
    assert result == [{'color': 'black', 'loc': 'a11'}]

def test_single_play_uppercase(leela):
    leela.reset()
    result = leela.play('WHITE', 'A11')
    assert result == [{'color': 'white', 'loc': 'a11'}]

def test_reset(leela):
    leela.reset()
    leela.play('b', 'a11')
    leela.play('w', 'a13')
    leela.reset()
    assert leela.current_board == []
    assert leela.current_move == 0

I notice ALL my test will start with the call to reset my module! Is there any way to add this to the fixture, or how would you solve it?

Pseudo code for what I want:

@pytest.fixture(scope='module')
def leela(request):
    leela = leelaZeroWrapper.LeelaWrapper()
    def quit():
        leela.quit()
    def reset():
        leela.reset()
    request.addfinalizer(quit)
    request.add_between_test_resetter(reset)
    return leela

If the initial setup was not so heavy I would just skip this and let the class initialize every test. I have tried to look through the documentation for the request object but cannot find a suitable method. I assume this must be solved some other way. Any idea?

like image 673
hirolau Avatar asked Sep 17 '25 01:09

hirolau


1 Answers

Just introduce another fixture that performs the reset. Make it an autouse fixture so it perfoms automatically before each test:

@pytest.fixture(scope='module')
def leela():
    leela = leelaZeroWrapper.LeelaWrapper()
    yield leela
    leela.quit()

@pytest.fixture(autouse=True)
def reset(leela):
    leela.reset()


def test_single_play(leela):
    result = leela.play('b', 'a11')
    assert result == [{'color': 'black', 'loc': 'a11'}]

The default fixture scope is function, so the reset fixture will rerun before each test in module.

like image 131
hoefling Avatar answered Sep 19 '25 15:09

hoefling