Pytest getting test Information in classes other than testcase

2020-05-22 python pytest contextmanager

I am writing a test framework using pytest. Is there a way to get testcase object in classes other than testcase. For example utility classes.

I want to print the testcase name and some markers for the test in utility classes. Are these information available in some contextmanager?

Answers

You cannot directly access pytest test properties if you are not inside a test fixture or a hook function, as there is no fixed test case class as in unittest. Your best bet is probably to get this information in a fixture and store it globally for access from a utility function:

testinfo={} 

@pytest.fixture(autouse=True)
def test_info(request):
    global testinfo
    testinfo['name'] = request.node.name
    testinfo['markers'] = [m.name for m in request.node.iter_markers()]
    ...
    yield  # the information is stored at test start... 
    testinfo = {}  # ... and removed on test teardown 

def utility_func():
    if testinfo:
        print(f"Name: {testinfo['name']} Markers: {testinfo['markers']}")
   ... 

Or, the same if you use a test class:

class TestSomething:
    def setup_method(self):
        self.testinfo = {}

    @pytest.fixture(autouse=True)
    def info(self, request):
        self.testinfo['name'] = request.node.name
        self.testinfo['markers'] = [m.name for m in
                                    request.node.iter_markers()]
        yield  # the information is stored at test start...
        self.testinfo = {}  # ... and removed on test teardown

    def utility_func(self):
        if self.testinfo:
            print(f"Name: {self.testinfo['name']} Markers:"
                  f" {self.testinfo['markers']}")

    @pytest.mark.test_marker
    def test_something(self):
        self.utility_func()
        assert True

This will show the output:

Name: test_something Markers: ['test_marker']

This will work if you call the utility function during test execution - otherwise no value will be set.

Note however that this will only work reliably if you execute the test synchronously. If using pytest-xdist or similar tools for asynchronous test execution, this may not work due to the testinfo variable being overwitten by another test (though that depends on the implementation - it may work, if the variables are copied during a test run). In that case you can to do the logging directly in the fixture or hook function (which may generally be a better idea, depending on your use case).

For more information about available test node properties you can check the documentation of a request node.

Related