pytest session scoped fixtures

In pytest fixtures nuts and bolts, I noted that you can specify session scope so that a fixture will only run once per test session and be available across multiple test functions, classes, and modules.

In this post, I’m going to show a simple example so you can see it in action.

Here’s the table from the previous post:

function Run once per test
class Run once per class of tests
module Run once per module
session Run once per session

A separate file for fixtures, conftest.py

With function, class, and module scope, it is completely reasonable for the fixture code to be in the same file as the tests.
But now suddenly, with session, that doesn’t make sense anymore.

We can put them in conftest.py. This is a special named file that pytest looks for.
The documentation says that it’s for local plugins, but we can use it for local fixtures as well. See the pytest.org site for placement and scope of conftest.py.

Simple example of session scope fixtures

I think it’s clearest to just see this in action.

I’ve got 4 files:

  • conftest.py
    • 2 fixtures
    • my_own_session_run_at_beginning, an autouse fixture with session scope
    • some_resource, a normal non-autouse fixture with session scope
  • test_alpha.py
    • 2 simple test functions
    • test_alpha_1, has no named fixtures
    • test_alpha_2, has one named fixture, some_resource
  • test_beta.py
    • similar to test_alpha.py, but with unittest based tests
  • test_gamma.py
    • similar to test_alpha.py, but with class based tests

conftest.py:

test_alpha.py:

test_beta.py:

test_gamma.py:

Output

Run with pytest -s -v

Mixing function, module, and session scope

Let’s say I’ve got:

  • a function scope fixture ‘resource_c’
  • that uses a module scoped fixture ‘fixture_b’
  • that uses a session scoped fixture ‘fixture_a’

This all works fine.
Also in this example, I’ve added a few autouse fixtures just for fun.

conftest.py:

test_one_two.py:

test_three_four.py:

This seems reasonable to me.
What do you think will happen?

output:

WARNING: you gotta use bigger and bigger scope

If you do this in the wrong order, things go haywire.

Let’s swap scope on a couple of items.

conftest.py:

We will get some warning like this (or several):

So. Don’t do that.

Warning applies to built in fixtures

Pytest includes some built in fixtures. I believe all of them are function scoped.
This means that you cannot use them from anything other than functions or function scoped fixtures.

Taking it further

The code I’ve shown is for simple run at the beginning and end type fixtures.
However, there’s more you can do with session fixtures.
The pytest.org site has a cool example, A session-fixture which can look at all collected tests.

What are you using session fixtures for?

I’d love to hear examples and use cases for session fixtures.
Please leave a comment or let me know @brianokken of how you are using them.

Comments

  1. Suresh V says

    How do you test a session scoped fixture? Can you use pytest.mark.parameterize on them? I am beginning to feel providing session scoped fixtures in a package are a PITA and not worth the effort.

    • says

      Suresh, I guess I don’t know what the problem is without more information.
      If you could describe roughly what functionality your package is helping you with, or even some specific code examples might help if you can show a boiled down example of some package and a fixture you want to run on it.

      In the meantime, I’ll try pull together an example of testing a session scoped fixture. Not sure of the time frame for when I’ll get this done.

  2. says

    Hello. I love these examples for use of conftest. What I have a need though is to pass common “configuration” data to each test suite. This is configuration of what environment I’m testing against, setting up logging, etc. Is there a way of using data from “resource_a” in a test suite/class?

    • says

      Absolutely. I’ll try to write up an example to show you it working.
      I’d like to know where you are getting the information that could change for each run.
      It makes a difference as to how you would set up the fixture.
      In the meantime, remember that the fixture name passed into the test function is the object returned by the fixture function.
      That can be anything.

      It can be a function that the test needs to call for something.
      It can be an object that contains useful tidbits of info.
      It can be a single value, if that’s all that’s needed.

      I’ll try to show all in action in a future post.
      … no time frame on that though, …. sorry..

Leave a Reply