irctest/conftest.py

95 lines
3.4 KiB
Python

import importlib
import sys
import unittest
import pytest
import _pytest.unittest
from irctest.cases import _IrcTestCase, BaseClientTestCase, BaseServerTestCase
from irctest.basecontrollers import BaseClientController, BaseServerController
def pytest_addoption(parser):
"""Called by pytest, registers CLI options passed to the pytest command."""
parser.addoption("--controller", help="Which module to use to run the tested software.")
parser.addoption('--openssl-bin', type=str, default='openssl',
help='The openssl binary to use')
def pytest_configure(config):
"""Called by pytest, after it parsed the command-line."""
module_name = config.getoption("controller")
if module_name is None:
pytest.exit("--controller is required.", 1)
try:
module = importlib.import_module(module_name)
except ImportError:
pytest.exit('Cannot import module {}'.format(module_name), 1)
controller_class = module.get_irctest_controller_class()
if issubclass(controller_class, BaseClientController):
from irctest import client_tests as module
elif issubclass(controller_class, BaseServerController):
from irctest import server_tests as module
else:
pytest.exit(
r'{}.Controller should be a subclass of '
r'irctest.basecontroller.Base{{Client,Server}}Controller'
.format(module_name),
1
)
_IrcTestCase.controllerClass = controller_class
_IrcTestCase.controllerClass.openssl_bin = config.getoption("openssl_bin")
_IrcTestCase.show_io = True # TODO
def pytest_collection_modifyitems(session, config, items):
"""Called by pytest after finishing the test collection,
and before actually running the tests.
This function filters out client tests if running with a server controller,
and vice versa.
"""
# First, check if we should run server tests or client tests
if issubclass(_IrcTestCase.controllerClass, BaseServerController):
server_tests = True
elif issubclass(_IrcTestCase.controllerClass, BaseClientController):
server_tests = False
else:
assert False, (
f"{_IrcTestCase.controllerClass} inherits neither "
f"BaseClientController or BaseServerController"
)
filtered_items = []
# Iterate over each of the test functions (they are pytest "Nodes")
for item in items:
# we only use unittest-style test function here
assert isinstance(item, _pytest.unittest.TestCaseFunction)
# unittest-style test functions have the node of UnitTest class as parent
assert isinstance(item.parent, _pytest.unittest.UnitTestCase)
# and that node references the UnitTest class
assert issubclass(item.parent.cls, unittest.TestCase)
# and in this project, TestCase classes all inherit either from BaseClientController
# or BaseServerController.
if issubclass(item.parent.cls, BaseServerTestCase):
if server_tests:
filtered_items.append(item)
elif issubclass(item.parent.cls, BaseClientTestCase):
if not server_tests:
filtered_items.append(item)
else:
assert False, (
f"{item}'s class inherits neither BaseServerTestCase "
"or BaseClientTestCase"
)
# Finally, rewrite in-place the list of tests pytest will run
items[:] = filtered_items