Skip to main content

utwist - Running twisted’s reactor inside regular unit-tests without trial

Unit testing with twisted is a bit difficult if the tests require the reactor to run. The official way is to use twisted’s own unit testing framework called trial. It is very similar to the unittest module. If you would like to use another framework, or if you like nice IDE integration then utwist might be the right thing for you.

Note that it is considered good practice to write unit tests that don’t perform IO. But for integration tests, and probably some unit-tests as well, you’ll need a reactor running.

Disclaimer: utwist is quite a hack. It works, I test it regularly on Linux, OSX, and Windows, but future versions of twisted might break it. You’ve been warned. Hopefully twisted will come in with a better testing solution eventually.

This library is open source and released under the MIT License.

You can install it with pip install utwist. It doesn’t need to compile anything, so there shouldn’t be any surprises. Even on Windows.

Let’s get going!

from utwist import with_reactor

@with_reactor
def test_connect_with_tcp():
  point = TCP4ClientEndpoint(reactor, "google.com", 80)
  d = point.connect(MyFactory())
  return d

If run with nose this will do exactly what you’d expect. It opens the network connection. The test will fail because the connection wasn’t closed. utwist checks that the reactor is clean at the end of the test.

Of course you don’t have to use nose. It works just as well with unittest, and probably also with most other frameworks.

Deferred return values

If the test function returns a deferred then the test will be successful if the deferred resolves to a value or unsuccessful if the deferred errbacks.

Setup and tear-down

If there is a function called twisted_setup() in the same class as the test function is defined, then this function will be invoked before the test, but already in the context of the reactor. Note that the regular setup function provided by the testing framework will be executed too, but not in the reactor context.

Accordingly, if there is a twisted_teardown() it executes after the test function, even if the test failed.

Setting a timeout

If the test, including twisted_setup and twisted_teardown, has not completed within the timeout, the test fails. The timeout defaults to two minutes. A timeout duration of zero disables the timeout.

To specify a different timeout pass it (in seconds) to the decorator:

@with_reactor(timeout=10)
def test_quick():
  ...

How does it work

I spare you the details, but utwist starts the reactor in a separate thread when the first test is started and lets it run until the end (the reactor cannot be restarted). It uses blockingCallFromThread() to run the test method inside the reactor. Other than that there are some tricks to check if the reactor is clean, and to clean it if not. There is also a very dirty hack to make signals work even though the reactor doesn’t run in the main thread.

Bug Reports and other contributions

This project is hosted here utwist github page.

Alternatives

If you don’t mind using a cut-down version of unittest for your tests, nor to run the tests with the special runner, then I highly recommend trial. It is the official unit testing tool provided by twisted.

Metadata

Release files for utwist 0.1.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for utwist 0.1.3
File Size Uploaded Provenance Actions
utwist-0.1.3.zip 15.8 kB Without provenance Details for utwist-0.1.3.zip

Release files / utwist-0.1.3.zip

Download URL utwist-0.1.3.zip
Size 15.8 kB
Tags Source
SHA-256 checksum
How to use checksums
b9d0aaca46f586421cf2fc1f924bd6d82a7607be6df3f0facdd4c67da6e784f5
BLAKE2b-256 checksum
How to use checksums
89795659163b2fd87cd28bde599bdf508792718017e29df9b77b76cda185afa3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No

Security for utwist 0.1.3

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page