Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Repeated use of fixtures in pytest

I am learning pytest, particularly its fixtures which are different from the xUnit setUp() and tearDown() paradigm. Say I have the following test:

import pytest


@pytest.fixture()
def foo():
    return 'foo'


@pytest.fixture()
def bar():
    return 'bar'


@pytest.fixture()
def baz():
    return 'baz'


@pytest.fixture()
def foobar(foo, bar):
    return foo + bar


@pytest.fixture()
def foobaz(foo, baz):
    return foo + baz


def test(foobar, foobaz):
    print('test')
    print(foobar)
    print(foobaz)

In this example, the foo() fixture is used twice, once by foobar() and again by foobaz(). If I reuse the same fixture multiple times for a single test, is the fixture function called once and its result cached? Or is it called each time that it is used? In my contrived example, the returned value is static, so there is no problems. I can imagine many situations where the returned value is more dynamic and I need to guarantee that I have the exact same instance everywhere it is used.

like image 643
Code-Apprentice Avatar asked Aug 23 '17 00:08

Code-Apprentice


People also ask

How often is a fixture function in pytest executed?

Fixtures with scope session will only be executed once per session. Every time you run pytest , it's considered to be one session.

How many times will a fixture of module scope run?

Module: If the Module scope is defined, the fixture will be created/invoked only once per module. Class: With Class scope, one fixture will be created per class object. Session: With the Session scope, the fixture will be created only once for entire test session.

Are pytest fixtures cached?

Pytest only caches one instance of a fixture at a time, which means that when using a parametrized fixture, pytest may invoke a fixture more than once in the given scope.

What is the use of fixtures in pytest?

Pytest fixtures are functions that can be used to manage our apps states and dependencies. Most importantly, they can provide data for testing and a wide range of value types when explicitly called by our testing software. You can use the mock data that fixtures create across multiple tests.


2 Answers

pytest fixture's life could be controlled with scope argument. There are basically four scopes function, class, module, session. The default scope is function which is the one your fixtures are using.

In the case of function scope, the fixture would be called for each test function on which the fixture is used.

A class scoped fixture is called once per test class through out the test cycle and so is module scoped fixture (once per test module).

A session scoped fixture is called once per test session.

More reading and examples for different scopes is available fixtures and fixture function

like image 141
Sanju Avatar answered Oct 17 '22 11:10

Sanju


A fixture is only called when it is used and it will be only called once based on the scope.

If the scope is session then it will only be called one for the whole execution. In your case since you have not specified the scope, it assumed function.

So below would be the execution order

foo
bar
foo + bar
baz
foo + baz

As you can see baz only called when foo + baz method was requested.

  • If you remove both the parameters from your test function. Nothing will be called even once.
  • If you remove foobaz then baz and foobaz will never be called
  • If you insert another function test2(foobar, foobaz), then whole cycle will be repeated as the scope of fixture is per/function
like image 28
Tarun Lalwani Avatar answered Oct 17 '22 12:10

Tarun Lalwani