~ubuntu-branches/ubuntu/trusty/twisted/trusty-proposed

« back to all changes in this revision

Viewing changes to doc/core/howto/testing.html

  • Committer: Package Import Robot
  • Author(s): Matthias Klose
  • Date: 2014-01-08 00:19:41 UTC
  • mfrom: (1.3.1) (44.2.2 sid)
  • Revision ID: package-import@ubuntu.com-20140108001941-kxhzbyi4a40sc08r
Tags: 13.2.0-1ubuntu1
* Merge with Debian; remaining changes:
  - Keep the preliminary python3 support, but don't enable it.
  - Try to use plain pygtkcompat and fall back to gi.pygtkcompat, to
    avoid a DeprecationWarning, and a crash.
  - Use new io_add_watch api on new versions of pygobject.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
<?xml version="1.0" encoding="utf-8"?><!DOCTYPE html  PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN'  'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'><html lang="en" xmlns="http://www.w3.org/1999/xhtml">
 
2
  <head>
 
3
<title>Twisted Documentation: Writing tests for Twisted code using Trial</title>
 
4
<link href="stylesheet.css" rel="stylesheet" type="text/css"/>
 
5
  </head>
 
6
 
 
7
  <body bgcolor="white">
 
8
    <h1 class="title">Writing tests for Twisted code using Trial</h1>
 
9
    <div class="toc"><ol><li><a href="#auto0">Trial basics</a></li><li><a href="#auto1">Trial directories</a></li><li><a href="#auto2">Twisted-specific quirks: reactor, Deferreds, callLater</a></li><ul><li><a href="#auto3">Leave the Reactor as you found it</a></li><li><a href="#auto4">Using Timers to Detect Failing Tests</a></li><li><a href="#auto5">Interacting with warnings in tests</a></li><li><a href="#auto6">Parallel test</a></li></ul></ol></div>
 
10
    <div class="content">
 
11
 
 
12
<span/>
 
13
 
 
14
<h2>Trial basics<a name="auto0"/></h2>
 
15
 
 
16
<p><strong>Trial</strong> is Twisted's testing framework.  It provides a
 
17
library for writing test cases and utility functions for working with the
 
18
Twisted environment in your tests, and a command-line utility for running your
 
19
tests. Trial is built on the Python standard library's <code>unittest</code>
 
20
module.</p>
 
21
 
 
22
<p>To run all the Twisted tests, do:</p>
 
23
 
 
24
<pre class="shell" xml:space="preserve">
 
25
$ trial twisted
 
26
</pre>
 
27
 
 
28
<p>Refer to the Trial man page for other command-line options.</p>
 
29
 
 
30
<h2>Trial directories<a name="auto1"/></h2>
 
31
 
 
32
<p>You might notice a new <code class="shell">_trial_temp</code> folder in the
 
33
current working directory after Trial completes the tests. This folder is the
 
34
working directory for the Trial process. It can be used by unit tests and 
 
35
allows them to write whatever data they like to disk, and not worry
 
36
about polluting the current working directory.</p>
 
37
 
 
38
<p>Folders named <code class="shell">_trial_temp-&lt;counter&gt;</code> are
 
39
created if two instances of Trial are run in parallel from the same directory,
 
40
so as to avoid giving two different test-runs the same temporary directory.</p>
 
41
 
 
42
<p>The <code class="API"><a href="http://twistedmatrix.com/documents/13.2.0/api/twisted.python.lockfile.html" title="twisted.python.lockfile">twisted.python.lockfile</a></code> utility is used to lock
 
43
the <code class="shell">_trial_temp</code> directories. On Linux, this results
 
44
in symlinks to pids. On Windows, directories are created with a single file with
 
45
a pid as the contents. These lock files will be cleaned up if Trial exits normally
 
46
and otherwise they will be left behind. They should be cleaned up the next time
 
47
Trial tries to use the directory they lock, but it's also safe to delete them
 
48
manually if desired.</p>
 
49
 
 
50
<h2>Twisted-specific quirks: reactor, Deferreds, callLater<a name="auto2"/></h2>
 
51
 
 
52
<p>The standard Python <code>unittest</code> framework, from which Trial is
 
53
derived, is ideal for testing code with a fairly linear flow of control.
 
54
Twisted is an asynchronous networking framework which provides a clean,
 
55
sensible way to establish functions that are run in response to events (like
 
56
timers and incoming data), which creates a highly non-linear flow of control.
 
57
Trial has a few extensions which help to test this kind of code. This section
 
58
provides some hints on how to use these extensions and how to best structure
 
59
your tests.</p>
 
60
 
 
61
<h3>Leave the Reactor as you found it<a name="auto3"/></h3>
 
62
 
 
63
<p>Trial runs the entire test suite (over four thousand tests) in a single
 
64
process, with a single reactor. Therefore it is important that your test
 
65
leave the reactor in the same state as it found it. Leftover timers may
 
66
expire during somebody else's unsuspecting test. Leftover connection attempts
 
67
may complete (and fail) during a later test. These lead to intermittent
 
68
failures that wander from test to test and are very time-consuming to track
 
69
down.</p>
 
70
 
 
71
<p>If your test leaves event sources in the reactor, Trial will fail the test.
 
72
The <code>tearDown</code> method is a good place to put cleanup code: it is
 
73
always run regardless of whether your test passes or fails (like a <code>finally</code>
 
74
clause in a try-except-finally construct). Exceptions in <code>tearDown</code>
 
75
are flagged as errors and flunk the test. 
 
76
 <code class="API"><a href="http://twistedmatrix.com/documents/13.2.0/api/twisted.trial.unittest.TestCase.addCleanup.html" title="twisted.trial.unittest.TestCase.addCleanup">TestCase.addCleanup</a></code> is
 
77
another useful tool for cleaning up.  With it, you can register callables to
 
78
clean up resources as the test allocates them.  Generally, code should be
 
79
written so that only resources allocated in the tests need to be cleaned up in
 
80
the tests.  Resources which are allocated internally by the implementation
 
81
should be cleaned up by the implementation.</p>
 
82
 
 
83
<p>If your code uses Deferreds or depends on the reactor running, you can
 
84
return a Deferred from your test method, setUp, or tearDown and Trial will
 
85
do the right thing. That is, it will run the reactor for you until the
 
86
Deferred has triggered and its callbacks have been run. Don't use 
 
87
 <code>reactor.run()</code>, <code>reactor.stop()</code>, <code>reactor.crash()</code> or <code>reactor.iterate()</code> in your tests.</p>
 
88
 
 
89
<p>Calls to <code>reactor.callLater</code> create <code class="API"><a href="http://twistedmatrix.com/documents/13.2.0/api/twisted.internet.interfaces.IDelayedCall.html" title="twisted.internet.interfaces.IDelayedCall">IDelayedCall</a></code>s.  These need to be run
 
90
or cancelled during a test, otherwise they will outlive the test.  This would
 
91
be bad, because they could interfere with a later test, causing confusing
 
92
failures in unrelated tests!  For this reason, Trial checks the reactor to make
 
93
sure there are no leftover <code class="API"><a href="http://twistedmatrix.com/documents/13.2.0/api/twisted.internet.interfaces.IDelayedCall.html" title="twisted.internet.interfaces.IDelayedCall">IDelayedCall</a></code>s in the reactor after a
 
94
test, and will fail the test if there are.  The cleanest and simplest way to
 
95
make sure this all works is to return a Deferred from your test.</p>
 
96
 
 
97
<p>Similarly, sockets created during a test should be closed by the end of the
 
98
test.  This applies to both listening ports and client connections.  So, calls
 
99
to <code>reactor.listenTCP</code> (and <code>listenUNIX</code>, and so on)
 
100
return <code class="API"><a href="http://twistedmatrix.com/documents/13.2.0/api/twisted.internet.interfaces.IListeningPort.html" title="twisted.internet.interfaces.IListeningPort">IListeningPort</a></code>s, and these should be
 
101
cleaned up before a test ends by calling their <code class="API"><a href="http://twistedmatrix.com/documents/13.2.0/api/twisted.internet.interfaces.IListeningPort.stopListening.html" title="twisted.internet.interfaces.IListeningPort.stopListening">stopListening</a></code> method.
 
102
Calls to <code>reactor.connectTCP</code> return <code class="API"><a href="http://twistedmatrix.com/documents/13.2.0/api/twisted.internet.interfaces.IConnector.html" title="twisted.internet.interfaces.IConnector">IConnector</a></code>s, which should be cleaned
 
103
up by calling their <code class="API"><a href="http://twistedmatrix.com/documents/13.2.0/api/twisted.internet.interfaces.IConnector.disconnect.html" title="twisted.internet.interfaces.IConnector.disconnect">disconnect</a></code> method.  Trial
 
104
will warn about unclosed sockets.</p>
 
105
 
 
106
<p>The golden rule is: If your tests call a function which returns a Deferred,
 
107
your test should return a Deferred.</p>
 
108
 
 
109
<h3>Using Timers to Detect Failing Tests<a name="auto4"/></h3>
 
110
 
 
111
<p>It is common for tests to establish some kind of fail-safe timeout that
 
112
will terminate the test in case something unexpected has happened and none of
 
113
the normal test-failure paths are followed. This timeout puts an upper bound
 
114
on the time that a test can consume, and prevents the entire test suite from
 
115
stalling because of a single test. This is especially important for the
 
116
Twisted test suite, because it is run automatically by the buildbot whenever
 
117
changes are committed to the Subversion repository.</p>
 
118
 
 
119
<p>The way to do this in Trial is to set the <code>.timeout</code> attribute
 
120
on your unit test method.  Set the attribute to the number of seconds you wish
 
121
to elapse before the test raises a timeout error.  Trial has a default timeout
 
122
which will be applied even if the <code>timeout</code> attribute is not set.
 
123
The Trial default timeout is usually sufficient and should be overridden only
 
124
in unusual cases.</p>
 
125
 
 
126
<h3>Interacting with warnings in tests<a name="auto5"/></h3>
 
127
 
 
128
<p>Trial includes specific support for interacting with Python's 
 
129
 <code>warnings</code> module.  This support allows warning-emitting code to
 
130
be written test-driven, just as any other code would be.  It also improves
 
131
the way in which warnings reporting when a test suite is running.</p>
 
132
 
 
133
<p><code class="API"><a href="http://twistedmatrix.com/documents/13.2.0/api/twisted.trial.unittest.TestCase.flushWarnings.html" title="twisted.trial.unittest.TestCase.flushWarnings">TestCase.flushWarnings</a></code>
 
134
allows tests to be written which make assertions about what warnings have
 
135
been emitted during a particular test method. In order to test a warning with 
 
136
 <code>flushWarnings</code>, write a test which first invokes the code which
 
137
will emit a warning and then calls <code>flushWarnings</code> and makes
 
138
assertions about the result.  For example:</p>
 
139
 
 
140
<pre class="python"><p class="py-linenumber">1
 
141
2
 
142
3
 
143
4
 
144
</p><span class="py-src-keyword">class</span> <span class="py-src-identifier">SomeWarningsTests</span>(<span class="py-src-parameter">TestCase</span>):
 
145
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">test_warning</span>(<span class="py-src-parameter">self</span>):
 
146
        <span class="py-src-variable">warnings</span>.<span class="py-src-variable">warn</span>(<span class="py-src-string">&quot;foo is bad&quot;</span>)
 
147
        <span class="py-src-variable">self</span>.<span class="py-src-variable">assertEqual</span>(<span class="py-src-variable">len</span>(<span class="py-src-variable">self</span>.<span class="py-src-variable">flushWarnings</span>()), <span class="py-src-number">1</span>)
 
148
</pre>
 
149
 
 
150
<p>Warnings emitted in tests which are not flushed will be included by the
 
151
default reporter in its output after the result of the test.  If Python's
 
152
warnings filter system (see <a href="http://docs.python.org/using/cmdline.html#cmdoption-unittest-discover-W" shape="rect">the
 
153
-W command option to Python</a>) is configured to treat a warning as an error,
 
154
then unflushed warnings will causes tests to fail and will be included in
 
155
the summary section of the default reporter.  Note that unlike usual
 
156
operation, when <code>warnings.warn</code> is called as part of a test
 
157
method, it will not raise an exception when warnings have been configured as
 
158
errors.  However, if called outside of a test method (for example, at module
 
159
scope in a test module or a module imported by a test module) then it 
 
160
 <em>will</em> raise an exception.</p>
 
161
 
 
162
<h3>Parallel test<a name="auto6"/></h3>
 
163
 
 
164
<p>In many situations, your unit tests may run faster if they are allowed to
 
165
run in parallel, such that blocking I/O calls allow other tests to continue.
 
166
Trial, like unittest, supports the -j parameter.  Run <code>trial -j 3</code>
 
167
to run 3 test runners at the same time.</p>
 
168
 
 
169
<p>This requires care in your test creation.  Obviously, you need to ensure that
 
170
your code is otherwise content to work in a parallel fashion while working within
 
171
Twisted... and if you are using weird global variables in places, parallel tests
 
172
might reveal this.</p>
 
173
 
 
174
<p>However, if you have a test that fires up a schema on an external database
 
175
in the <code>setUp</code> function, does some operations on it in the test, and
 
176
then deletes that schema in the tearDown function, your tests will behave in an
 
177
unpredictable fashion as they tromp upon each other if they have their own
 
178
schema.  And this won't actually indicate a real error in your code, merely a
 
179
testing-specific race-condition.</p>
 
180
 
 
181
  </div>
 
182
 
 
183
    <p><a href="index.html">Index</a></p>
 
184
    <span class="version">Version: 13.2.0</span>
 
185
  </body>
 
186
</html>
 
 
b'\\ No newline at end of file'