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-cov
to integrate withcoverage-py
pytest-sugar
to provide better uxpytest-print
to give some progress indicator and to assist test troubleshootingpytest-profiling
to implement*-profile
testenv, 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:port
defined inGlobal.SrvAddr
unless 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_controller
also fetches all*args
and**kwargs
parameters 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_handler
also fetches all*args
and**kwargs
parameters fromhandler_data()
marker.
- fixture aiosmtpd.tests.conftest.nodecode_controller
Scope: function
Same as
plain_controller
, except thatdecode_data=False
is enforced.This is actually identical to using
plain_controller
with 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_controller
andget_handler
fixtures, 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
_ProactorBasePipeTransport
raising 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
client
fixture.- Parameters:
connect_to (
HostPort
) – Address to connect to. Defaults toGlobal.SrvAddr
- @controller_data(...)
Provides parameters to the
get_controller
fixture.- Parameters:
class_ – The class to be instantiated by
get_controller
. Will be overridden ifget_controller
is 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_handler
fixture.- 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.