1
votes

I have a below py.test program where i need to 2 fixtures, one with scope "session" and other with scope "class", the fixture with scope "class" takes fixture with "session" as one of it's argument.

While running tests that uses scope as "class", the tests seems to run twice,

Below is the code.

import pytest

@pytest.fixture(scope="session")
def session_fixture(request):
    data = ['hello world']
    return data

@pytest.fixture(scope="class")
def class_fixture(session_fixture, request):
    if hasattr(request.cls, 'test1'):
        request.cls().test1(session_fixture)
    return session_fixture

class TestClass:
    def test1(self,class_fixture):
        print("Hello World")

When i run the test, it seems to print "hello world" twice.

Ouput:

$ py.test test7.py -s
=============== test session start============================
platform linux2 -- Python 2.7.5 -- py-1.4.27 -- pytest-2.7.0
rootdir: /root/fix2, inifile: 
plugins: multihost
collected 1 items 

test7.py Hello World
Hello World
. 
================ 1 passed in 0.09 seconds ===================

In the above program if i use the fixture "session_fixture" directly instead of "class_fixture", i see that "Hello world" is printed only once.

Any hints on how i could resolve the issue.

1

1 Answers

2
votes

Your 'test' case seems to be incorrect

import pytest

@pytest.fixture(scope="session")
def session_fixture(request):
    data = ['hello world']
    print("Session fixture")
    return data

@pytest.fixture(scope="class")
def class_fixture(session_fixture, request):
    print("Class fixture")
    return session_fixture


class TestClass:
    def test1(self,class_fixture):
        print("Hello World 1")

    def test2(self, class_fixture):
        print('Hello World 2')

this gives:

py.test test.py -s

collected 2 items 

test.py::TestClass::test1 Session fixture
Class fixture
Hello World 1
PASSED
test.py::TestClass::test2 Hello World 2
PASSED

So class-based fixture is executed only once. Pytest has massive test coverage on simple cases like this to be sure it always works as declared.