Initial import to Tizen
[profile/ivi/python-twisted.git] / doc / core / howto / testing.html
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></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/12.1.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/12.1.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/12.1.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/12.1.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/12.1.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/12.1.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/12.1.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/12.1.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/12.1.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   </div>
163
164     <p><a href="index.html">Index</a></p>
165     <span class="version">Version: 12.1.0</span>
166   </body>
167 </html>