I have a conftest.py:
import pytest
import asyncio
from some_library import MyLibrary
@pytest.fixture()
def event_loop(request):
loop = asyncio.get_event_loop_policy().new_event_loop()
yield loop
loop.close()
@pytest.fixture(name="library_instance", scope='session')
def fixture_library_instance():
library = MyLibrary()
print("\nSetup Library")
library.config()
yield library
print("\nTeardown Library")
library = None
And a test file (test_1.py):
import pytest
class Test_Somemore:
@classmethod
def setup_class(self):
print("\nSetup Class")
@classmethod
def teardown_class(self):
print("\nTeardown Class")
@classmethod
def setup_method(self, method):
print("\nSetup Test = ", method.__name__)
@classmethod
def teardown_method(self, method):
print("\nTeardown Test = ", method.__name__)
@pytest.mark.usefixtures("library_instance")
@pytest.mark.asyncio
async def test_something_4(self, library_instance):
print(f"\ntest 4 - {library_instance.var}")
assert 1 == 1
assert library_instance.var == 100
@pytest.mark.usefixtures("library_instance")
@pytest.mark.asyncio
async def test_something_5(self, library_instance):
print(f"\ntest 5 - {library_instance.var}")
assert 2 == 2
assert library_instance.var == 100
@pytest.mark.usefixtures("library_instance")
@pytest.mark.asyncio
async def test_something_6(self, library_instance):
print(f"\ntest 6 - {library_instance.var}")
assert 3 == 3
assert library_instance.var == 100
The order it is being called is:
- Setup Library
- Setup Class
- Setup Test (test 4)
- Teardown Test (test 4)
- Setup Test (test 5)
- Teardown Test (test 5)
- Setup Test (test 6)
- Teardown Test (test 6)
- Teardown Class
- Teardown Libary
This is ok.
What I need is the following:
- To have library_instance (from the fixture "fixture_library_instance") callable inside the setup_class, teardown_class, setup_method, and teardown_method. Not just the test cases. I haven't found a way to make this work.
- In teardown_method, check if the test has failed. If it did, I want to call some functions.
Basically something like this:
@classmethod
def setup_class(self):
print("\nSetup Class")
library_instance.foo1()
@classmethod
def teardown_class(self):
print("\nTeardown Class")
library_instance.foo2()
@classmethod
def setup_method(self, method):
print("\nSetup Test = ", method.__name__)
library_instance.foo3()
@classmethod
def teardown_method(self, method):
print("\nTeardown Test = ", method.__name__)
if test == FAIL:
library_instance.foo4()
Can somebody please help me?
Both your requirements are possible.
The first one (accessing another fixture in a setup method) is trivial if you change your setup/teardown methods to fixtures. In this case, you can just reference other fixtures of the same or a wider scope:
A few remarks:
setup_classandsetup_methodbut changed them for illustration. As soon as you make them fixtures, the name does not matter.autouse=True(quite obvious, but I wanted to mention it).methodargument as insetup_methodwon't work (it will be seen as a fixture name), but you can get the name via therequestfixture instead.Using the fixture notation arguably is preferrable to separate setup/teardown methods, as it only needs one method, and also allows the use of the same local variables for both setup and teardown (e.g. before and after the
yield), though that is also a matter of taste.As for the second part (checking if a fixture has failed) - this has been nicely answered here, with a link to the relevant documentation, so I won't repeat it here.