Testing Mixins¶
Collection of functionality mix-ins.
This module contains standalone classes that can be safely mixed
into the BaseTest class. Each mixin
extends the functionality of the test case by adding behaviors,
methods, and attributes - for example, patching well-understood
functionality or automatically creating/destroying an in memory
UDP server.
When creating a mixin it is important to take not that you
should strive to keep the Method Resolution Order (MRO) as clean
as possible. Each mixin class should ideally only inherit from
object.
-
class
test_helpers.mixins.EnvironmentMixin¶ Mix this class in if you manipulate environment variables.
A common problem in testing code that uses environment variables is forgetting that they are really globals that persist between tests. This mixin exposes methods that make it easy and safe to set and unset environment variables while ensuring that the environment will be restored when the test has completed.
You need to mix this in over a class that calls the
configureannihilateclass methods around the code under test such astest_helpers.bases.BaseTest.-
classmethod
annihilate()¶
-
classmethod
configure()¶
-
classmethod
set_environment_variable(name, value)¶ Set the value of an environment variable.
-
classmethod
unset_environment_variable(name)¶ Clear an environment variable.
-
classmethod
-
class
test_helpers.mixins.PatchMixin¶ A mixin to allow inline patching and automatic un-patching.
This mixin adds one new method,
create_patchthat will create and activate patch objects without having to use the decorator.In order to make use of the patching functionality you need to set the
patch_prefixclass attribute. This attribute should be the python module path whose objects you want to patch. For example, if you wanted to patch thebazobject in thefoo.barmodule your patch prefix might look likefoo.bar. When creating a patch you can now just refer to the object name likecls.create_patch('baz').This usage of this mixin as opposed to the patch decorator results in less pylint errors and not having to think about the order of decorator application.
Example Usage:
class MyTest(mixins.PatchMixin, bases.BaseTest): patch_prefix = 'my_application.module.submodule' @classmethod def configure(cls): cls.foo_mock = cls.create_patch('foo') cls.bar_mock = cls.create_patch('bar', return_value=100) @classmethod def execute(cls): function_under_test() def should_call_foo(self): self.foo_mock.assert_called_once_with() def should_return_100_from_bar(self): self.assertEqual(100, self.bar_mock.return_value)
-
classmethod
create_patch(target, **kwargs)¶ Create and apply a patch.
This method calls
mock.patch()with the keyword parameters and returns the running patch. This approach has the benefit of applying a patch without scoping the patched code which, in turn, lets you apply patches without having to overridesetUpClass()to do it.Parameters: target (str) – the target of the patch. This is passed as an argument to cls.patch_prefix.format()to create the fully-qualified patch target.
-
patch_prefix= ''¶
-
classmethod
setUpClass()¶
-
classmethod
stop_patches()¶ Stop any active patches when the class is finished.
-
classmethod
tearDownClass()¶
-
classmethod
Tornado Specific Helpers¶
-
class
test_helpers.mixins.tornado.JsonMixin¶ Mix in over
TornadoMixinto enable JSON handling.This mix in extends
TornadoMixin.request()so that it will automatically serialize request data and deserialize responses as JSON. It does honor the HTTP content type headers so it will not accidentally deserialize a non-JSON response or serialize an already serialized request.-
classmethod
request(*args, **kwargs)¶ Send a request and process the response.
Parameters: - args – positional parameters to send to
super().request - kwargs – keyword parameters to send to
super().request
Returns: either a
tornado.httpclient.HTTPResponseinstance orNoneif the request timed out.- args – positional parameters to send to
-
classmethod
-
class
test_helpers.mixins.tornado.TornadoMixin¶ Test tornado applications with AAA testing.
Mix this class in over
test_helpers.bases.BaseTestor similar classmethod-based testing class and you can directly test tornado-based applications.Usage
from unittest import TestCase import test_helpers.mixins.tornado import myproject class WhenMyApplicationsGets(mixins.tornado.TornadoMixin, TestCase): @classmethod def setUpClass(cls): super(WhenMyApplicationGets, cls).setUpClass() cls.start_tornado(myproject.Application()) cls.execute() @classmethod def tearDownClass(cls): super(WhenMyApplicationGets, cls).tearDownClass() cls.stop_tornado() @classmethod def execute(cls): cls.response = cls.get('/index') def should_return_ok(self): self.assertEqual(self.response.code, 200)
Attributes
This mix-in creates three useful attributes in addition to the methods. Each of the attributes is initialized by
start_tornado()and will beNoneuntil that method is called.-
client¶ The
tornado.httpclient.HTTPClientinstance used to interact with the application.
-
io_loop¶ The
tornado.ioloop.IOLoopinstance that the application is attached to.
-
url_root¶ The URL root used to interact with the application. This refers to host and port that
io_loopis attached to.
-
request_timeout¶ The number of seconds to run the IO loop for before giving up on the request.
-
classmethod
delete(path, **kwargs)¶ Issue a
DELETErequest.
-
classmethod
get(path, **kwargs)¶ Issue a
GETrequest.
-
classmethod
head(path, **kwargs)¶ Issue a
HEADrequest.
-
classmethod
options(path, **kwargs)¶ Issue a
OPTIONSrequest.
-
classmethod
patch(path, body, **kwargs)¶ Issue a
PATCHrequest.
-
classmethod
post(path, body, **kwargs)¶ Issue a
POSTrequest.
-
classmethod
put(path, body, **kwargs)¶ Issue a
PUTrequest.
-
classmethod
request(method, path, **kwargs)¶ Issue a request to the application.
Parameters: - method (str) – HTTP method to invoke
- path (str) – possibly absolute path of the resource to invoke
- kwargs – additional arguments passed to the
tornado.httpclient.HTTPRequestinitializer
Returns: either a
tornado.httpclient.HTTPResponseinstance orNoneif the request timed out.The path parameter can be a relative path or an absolute URL. It will be joined to
url_rootbefore the request object is created.
-
classmethod
start_tornado(application)¶ Start up tornado and register application.
Parameters: application – anything suitable as a Tornado request callback (see tornado.httpserver.HTTPServer)This method binds a socket to an arbitrary temporary port, creates a new Tornado IOLoop, and adds the application‘ to it. Calling any of the request-related methods will start the IOLoop and run it until a response is received.
-
classmethod
stop_tornado()¶ Terminate the tornado IO loop.
-
-
class
test_helpers.mixins.tornado.TornadoTest(methodName='runTest')¶ Tornado version of
BaseTest.This class acts as a replacement for
BaseTestwith the Tornado magic pre-mixed. All that you have to do is:- set
tornado_applicationas a top-level class attribute OR - pass the
applicationkeyword toconfigure()and make sure that this class is the first one in the__mro__
In either case, the
applicationis the Tornado request callback that is being tested. Seetornado.httpserver.HTTPServerfor a complete description of what constitutes a “request callback”.-
classmethod
annihilate()¶ Terminates the Tornado application.
-
classmethod
configure(application=None)¶ Configures the Tornado IOLoop.
Parameters: application – overrides tornado_application
-
tornado_application= None¶ The Tornado request handler callable.
- set