2

I am working on a fairly versatile Python data structure while writing tests for every bit of functionality. Most of the tests re-instantiate the same structure, i.e. with the same values, such that a specific method can be tested. For example:

class T():
    def __init__(self, data):
        self.data = data

    def min(self):
        return 'min'

    def max(self):
        return 'max'

class TestT():
    def test_min():
        t = T(values)

        assert t.min() == 'min'

    def test_max():
        t = T(values)

        assert t.max() == 'max'

What is the proper way of re-using this t instance? I am only beginning and the tests are starting to take too long to execute. I want to speed them up.

Note: I am aware I could parametrize and getattr in this particular example but it would still instantiate t twice, once for each test.

Attempts

I looked at pytest.fixtures however it seems that making a fixture return this t would just do the same thing, re-instantiating it.

Pytest cache seems to be made for this but I do not understand from the documentation how to use it (what is request in the example?).

Lastly, just storing t in a (class) variable doesn't seem to speed up the tests.

Dimebag
  • 833
  • 2
  • 9
  • 29
  • 3
    Did you scroll down and look at [this](https://docs.pytest.org/en/latest/fixture.html#scope-sharing-a-fixture-instance-across-tests-in-a-class-module-or-session)? – Scratch'N'Purr Sep 07 '18 at 13:40
  • 1
    _it seems that making a fixture return this t would just do the same thing, re-instantiating it._ - why do you think that? A fixture can be made session-scoped; the return value of a fixture marked with `scope='session'` will thus only be instantiated once per test run. – hoefling Sep 09 '18 at 09:57
  • 1
    Maybe you have already done it, but, with every performance related problem, an ounce of profiling is worth several pounds of guessing. https://stackoverflow.com/questions/18830232/can-i-run-line-profiler-over-a-pytest-test – xverges Sep 09 '18 at 16:09
  • @xverges that really helps, nice! – Dimebag Sep 10 '18 at 09:11

1 Answers1

1

It seems that my understanding of pytest fixtures was incomplete. The following works just fine:

class Test():
    @pytest.fixture(scope='class')
    def data(self):
        return ...

    def test_min(data):
        assert data.min() == 'min'

    def test_max(data):
        assert data.max() == 'max'
Dimebag
  • 833
  • 2
  • 9
  • 29