Use pytest_pycollect_makeitem
to customize how tests are collected
from classes
By default py.test collects all classes which start with Test
that are found
in test*.py
or *test.py
modules. This behavior can be configured using the
python_classes
and python_files
configuration
options.
Also, it will out-of-the box collect classes which subclass unittest.TestCase
(regardless of their name), making it easy to run existing test suites.
But thanks to py.test's flexible plugin architecture, one can customize how tests are collected from classes to suit almost any requirement.
Recently someone asked in the pytest-dev mailing list how to make py.test collect all classes, that subclass from some specific base class, independently of their name.
Suppose all your test classes subclass from a certain utility class:
class TestingUtils(object):
def connect_to_database(self):
...
def validate_ui(self):
...
And all your tests are written in functions in subclasses of TestingUtils
,
but that don't follow any particular naming convention:
class BorgTests(TestingUtils):
def test_borg_creation(self):
db = self.connect_to_database()
...
class ValidationRules(TestingUtils):
def test_rule_1(self):
...
You can implement your own collection rules by implementing the pytest_pycollect_makeitem hook.
Simply add this code to a conftest.py
file at the root of your tests'
directory and that's it:
import inspect
def pytest_pycollect_makeitem(collector, name, obj):
if inspect.isclass(obj) and issubclass(obj, TestingUtils):
Class = collector._getcustomclass("Class")
return Class(name, parent=collector)
This won't interfere with the normal test collection mechanism, only add to it,
so classes prefixed with Test
will also be collected as usual.
COMMENTS