Testing¶
Testing (which includes unit testing, integration testing, and regression testing) is very important for quality code; extremely so if the code is a library that will be used in other software.
Test Framework: pytest¶
aiosmtpd uses the pytest testing framework.
Advanced features of pytest are widely used throughout.
Plugins¶
The one required plugin is pytest-mock;
it is used extensively throughout the test suite.
Other plugins that are used, to various degrees, in the aiosmtpd test suite are:
pytest-covto integrate withcoverage-pypytest-sugarto provide better uxpytest-printto give some progress indicator and to assist test troubleshootingpytest-profilingto implement*-profiletestenv, although to be honest this is not really useful as the profiling gets ‘muddied’ by pytest runner.
Fixtures¶
Below is a list of fixtures defined throught the test suite, in alphabetical order:
- fixture aiosmtpd.tests.conftest.client¶
Scope: function
Generic SMTP Client, will connect to the
host:portdefined inGlobal.SrvAddrunless overriden usingclient_data()marker.
- fixture aiosmtpd.tests.conftest.get_controller¶
Scope: function
Provides a function that will return an instance of a controller.
Default class of the controller is Controller, but can be changed via the
class_parameter to the function, or via theclass_parameter ofcontroller_data()Example usage:
def test_case(get_controller): handler = SomeHandler() controller = get_controller(handler, class_=SomeController) ...
- Parameters:
class_ – The class of the controller to be instantiated. If given, overrides
class_arg ofcontroller_data(). If not specified and noclass_fromcontroller_data, defaults toExposingController.- Returns:
an instance of
Controller(or a subclass of)
In addition to explicitly-specified parameters,
get_controlleralso fetches all*argsand**kwargsparameters fromcontroller_data()marker.
- fixture aiosmtpd.tests.conftest.get_handler¶
Scope: function
Provides a function that will return an instance of a handler class.
Default class of the handler is Sink, but can be changed via the
class_parameter to the function, or via theclass_parameter ofhandler_data()Example usage:
def test_case(get_handler): handler = get_handler(class_=SomeHandler) controller = Controller(handler) ...
- Parameters:
class_ – The class of the handler to be instantiated. If given, overrides
class_arg ofhandler_data(). If not specified and noclass_fromhandler_data, defaults toSink.- Returns:
an instance of the handler class.
In addition to explicitly-specified parameters,
get_handleralso fetches all*argsand**kwargsparameters fromhandler_data()marker.
- fixture aiosmtpd.tests.conftest.nodecode_controller¶
Scope: function
Same as
plain_controller, except thatdecode_data=Falseis enforced.This is actually identical to using
plain_controllerwith marker@controller_data(decode_data=False). But because this is used in a lot of test cases, it’s tidier to just make this into a dedicated fixture.
- fixture aiosmtpd.tests.conftest.plain_controller¶
Scope: function
Returns a Controller that, by default, gets invoked with no optional args. Hence the moniker “plain”.
Internally uses the
get_controllerandget_handlerfixtures, so optional args/kwargs can be specified for the Controller and the handler via thecontroller_data()andhandler_data()markers, respectively.
- fixture aiosmtpd.tests.conftest.silence_event_loop_closed¶
Scope: module
Mostly used to suppress “unhandled exception” error due to
_ProactorBasePipeTransportraising an exception when doing__del__
- fixture aiosmtpd.tests.conftest.ssl_context_client¶
Scope: function
Provides a client-side SSL Context
- fixture aiosmtpd.tests.conftest.ssl_context_server¶
Scope: function
Provides a server-side SSL Context
Important
As long as you create your test module(s) inside the aiosmtpd/tests directory,
you do not need to import the above fixtures;
they will automatically be available for use as they are defined in the conftest.py file.
Note
Individual test modules may define their own module-specific fixtures; please refer to their respective docstrings for description / usage guide.
Markers¶
- @client_data(...)¶
Provides parameters to the
clientfixture.- Parameters:
connect_to (
HostPort) – Address to connect to. Defaults toGlobal.SrvAddr
- @controller_data(...)¶
Provides parameters to the
get_controllerfixture.- Parameters:
class_ – The class to be instantiated by
get_controller. Will be overridden ifget_controlleris invoked with theclass_argument.host_port (str) – The “host:port” to bound to
**kwargs – Keyworded arguments given to the marker.
- @handler_data(...)¶
Provides parameters to the
get_handlerfixture.- Parameters:
args_ – A tuple containing values that will be passed as positional arguments to the controller constructor
class_ – The class to be instantiated by
get_controller*args – Positional arguments given to the marker. Will override the
args_keyword argument**kwargs – Keyworded arguments given to the marker.