Twisted support

testtools provides support for testing Twisted code.

Matching Deferreds

testtools provides support for making assertions about synchronous Deferreds.

A “synchronous” Deferred is one that does not need the reactor or any other asynchronous process in order to fire.

Normal application code can’t know when a Deferred is going to fire, because that is generally left up to the reactor. Well-written unit tests provide fake reactors, or don’t use the reactor at all, so that Deferreds fire synchronously.

These matchers allow you to make assertions about when and how Deferreds fire, and about what values they fire with.

See also Testing Deferreds without the reactor and the Deferred howto.

testtools.twistedsupport.succeeded(matcher)

Match a Deferred that has fired successfully.

For example:

fires_with_the_answer = succeeded(Equals(42))
deferred = defer.succeed(42)
assert_that(deferred, fires_with_the_answer)

This assertion will pass. However, if deferred had fired with a different value, or had failed, or had not fired at all, then it would fail.

Use this instead of twisted.trial.unittest.SynchronousTestCase.successResultOf().

Parameters:matcher – A matcher to match against the result of a Deferred.
Returns:A matcher that can be applied to a synchronous Deferred.
testtools.twistedsupport.failed(matcher)

Match a Deferred that has failed.

For example:

error = RuntimeError('foo')
fails_at_runtime = failed(Equals(error))
deferred = defer.fail(error)
assert_that(deferred, fails_at_runtime)

This assertion will pass. However, if deferred had fired successfully, had failed with a different error, or had not fired at all, then it would fail.

Use this instead of twisted.trial.unittest.SynchronousTestCase.failureResultOf().

Parameters:matcher – A matcher to match against the result of a failing Deferred.
Returns:A matcher that can be applied to a synchronous Deferred.
testtools.twistedsupport.has_no_result()

Match a Deferred that has not yet fired.

For example, this will pass:

assert_that(defer.Deferred(), has_no_result())

But this will fail:

>>> assert_that(defer.succeed(None), has_no_result())
Traceback (most recent call last):
  ...
  File "testtools/assertions.py", line 22, in assert_that
    raise MismatchError(matchee, matcher, mismatch, verbose)
testtools.matchers._impl.MismatchError: No result expected on <Deferred at ... current result: None>, found None instead

As will this:

>>> assert_that(defer.fail(RuntimeError('foo')), has_no_result())
Traceback (most recent call last):
  ...
  File "testtools/assertions.py", line 22, in assert_that
    raise MismatchError(matchee, matcher, mismatch, verbose)
testtools.matchers._impl.MismatchError: No result expected on <Deferred at ... current result: <twisted.python.failure.Failure <type 'exceptions.RuntimeError'>>>, found <twisted.python.failure.Failure <type 'exceptions.RuntimeError'>> instead

Running tests in the reactor

testtools provides support for running asynchronous Twisted tests: tests that return a Deferred and run the reactor until it fires and its callback chain is completed.

Here’s how to use it:

from testtools import TestCase
from testtools.twistedsupport import AsynchronousDeferredRunTest

class MyTwistedTests(TestCase):

    run_tests_with = AsynchronousDeferredRunTest

    def test_foo(self):
        # ...
        return d

Note that you do not have to use a special base TestCase in order to run Twisted tests, you should just use the regular testtools.TestCase base class.

You can also run individual tests within a test case class using the Twisted test runner:

class MyTestsSomeOfWhichAreTwisted(TestCase):

    def test_normal(self):
        pass

    @run_test_with(AsynchronousDeferredRunTest)
    def test_twisted(self):
        # ...
        return d

Converting Trial tests to testtools tests