Show More
@@ -1,8 +1,8 | |||||
1 | .. _testing: |
|
1 | .. _testing: | |
2 |
|
2 | |||
3 | ========================= |
|
3 | ========================================== | |
4 | Writing and running tests |
|
4 | Testing IPython for users and developers | |
5 | ========================= |
|
5 | ========================================== | |
6 |
|
6 | |||
7 | Overview |
|
7 | Overview | |
8 | ======== |
|
8 | ======== | |
@@ -14,41 +14,342 IPython test system can detect. See below for more details on this. | |||||
14 | Each subpackage in IPython should have its own :file:`tests` directory that |
|
14 | Each subpackage in IPython should have its own :file:`tests` directory that | |
15 | contains all of the tests for that subpackage. All of the files in the |
|
15 | contains all of the tests for that subpackage. All of the files in the | |
16 | :file:`tests` directory should have the word "tests" in them to enable |
|
16 | :file:`tests` directory should have the word "tests" in them to enable | |
17 |
the testing framework to find them. |
|
17 | the testing framework to find them. | |
|
18 | ||||
|
19 | In docstrings, examples (either using IPython prompts like ``In [1]:`` or | |||
|
20 | 'classic' python ``>>>`` ones) can and should be included. The testing system | |||
|
21 | will detect them as doctests and will run them; it offers control to skip parts | |||
|
22 | or all of a specific doctest if the example is meant to be informative but | |||
|
23 | shows non-reproducible information (like filesystem data). | |||
18 |
|
24 | |||
19 | If a subpackage has any dependencies beyond the Python standard library, the |
|
25 | If a subpackage has any dependencies beyond the Python standard library, the | |
20 | tests for that subpackage should be skipped if the dependencies are not found. |
|
26 | tests for that subpackage should be skipped if the dependencies are not found. | |
21 | This is very important so users don't get tests failing simply because they |
|
27 | This is very important so users don't get tests failing simply because they | |
22 | don't have dependencies. We are still figuring out the best way for this |
|
28 | don't have dependencies. | |
23 | to be handled. |
|
29 | ||
|
30 | The testing system we use is a hybrid of nose_ and Twisted's trial_ test runner. | |||
|
31 | We use both because nose detects more things than Twisted and allows for more | |||
|
32 | flexible (and lighter-weight) ways of writing tests; in particular we've | |||
|
33 | developed a nose plugin that allows us to paste verbatim IPython sessions and | |||
|
34 | test them as doctests, which is extremely important for us. But the parts of | |||
|
35 | IPython that depend on Twisted must be tested using trial, because only trial | |||
|
36 | manages the Twisted reactor correctly. | |||
|
37 | ||||
|
38 | .. _nose: http://code.google.com/p/python-nose | |||
|
39 | .. _trial: http://twistedmatrix.com/trac/wiki/TwistedTrial | |||
|
40 | ||||
|
41 | ||||
|
42 | For the impatient: running the tests | |||
|
43 | ==================================== | |||
|
44 | ||||
|
45 | The simplest way to test IPython is to type at the command line: | |||
|
46 | ||||
|
47 | .. code-block:: bash | |||
|
48 | ||||
|
49 | python -c "import IPython; IPython.test()" | |||
|
50 | ||||
|
51 | This should work as long as IPython can be imported, even if you haven't fully | |||
|
52 | installed the user-facing scripts yet (common in a development environment). | |||
|
53 | After a lot of output, you should see something like: | |||
|
54 | ||||
|
55 | .. code-block:: bash | |||
|
56 | ||||
|
57 | ************************************************************************ | |||
|
58 | Ran 10 test groups in 35.228s | |||
|
59 | ||||
|
60 | OK | |||
|
61 | ||||
|
62 | If not, there will be a message indicating which test group failed and how to | |||
|
63 | rerun that group individually. | |||
|
64 | ||||
|
65 | But IPython ships with an entry point script called :file:`iptest` that offers | |||
|
66 | fine-grain control over the test process and is particularly useful for | |||
|
67 | developers; this script also manages intelligently both nose and trial, | |||
|
68 | choosing the correct test system for each of IPython's components. Running | |||
|
69 | :file:`iptest` without arguments gives output identical to that above, but with | |||
|
70 | it, you can also run specific tests with fine control. The :file:`iptest` | |||
|
71 | script is installed with IPython, but if you are running from a source tree, | |||
|
72 | you can find it in the :file:`IPython/scripts` directory and you can run | |||
|
73 | directly from there. | |||
|
74 | ||||
|
75 | For example, this tests the :mod:`IPython.utils` subpackage, the :option:`-v` | |||
|
76 | option shows progress indicators: | |||
|
77 | ||||
|
78 | .. code-block:: bash | |||
24 |
|
79 | |||
25 | Status |
|
80 | maqroll[ipython]> cd IPython/scripts/ | |
26 | ====== |
|
81 | maqroll[scripts]> ./iptest -v IPython.utils | |
|
82 | ..........................SS..SSS............................S.S......... | |||
|
83 | ................................................... | |||
|
84 | ---------------------------------------------------------------------- | |||
|
85 | Ran 125 tests in 0.070s | |||
27 |
|
86 | |||
28 | Currently IPython's testing system is being reworked. In the meantime, |
|
87 | OK (SKIP=7) | |
29 | we recommend the following testing practices: |
|
|||
30 |
|
88 | |||
31 | * To run regular tests, use the :command:`nosetests` command that Nose [Nose]_ |
|
89 | Because :file:`iptest` is based on nose, you can use all nose options and | |
32 | provides on a per file basis: |
|
90 | syntax, typing ``iptest -h`` shows all available options. For example, this | |
|
91 | lets you run the specific test :func:`test_rehashx` inside the | |||
|
92 | :mod:`test_magic` module: | |||
33 |
|
93 | |||
34 | .. code-block:: bash |
|
94 | .. code-block:: bash | |
35 |
|
95 | |||
36 |
|
|
96 | maqroll[scripts]> ./iptest -vv IPython.core.tests.test_magic:test_rehashx | |
|
97 | IPython.core.tests.test_magic.test_rehashx(True,) ... ok | |||
|
98 | IPython.core.tests.test_magic.test_rehashx(True,) ... ok | |||
37 |
|
99 | |||
38 | * To run Twisted-using tests, use the :command:`trial` command on a per file |
|
100 | ---------------------------------------------------------------------- | |
39 | basis: |
|
101 | Ran 2 tests in 0.101s | |
|
102 | ||||
|
103 | OK | |||
|
104 | ||||
|
105 | When developing, the :option:`--pdb` and :option:`--pdb-failures` of nose are | |||
|
106 | particularly useful, these drop you into an interactive pdb session at the | |||
|
107 | point of the error or failure respectively. | |||
|
108 | ||||
|
109 | To run Twisted-using tests, use the :command:`trial` command on a per file or | |||
|
110 | package basis: | |||
40 |
|
111 | |||
41 | .. code-block:: bash |
|
112 | .. code-block:: bash | |
42 |
|
113 | |||
43 | trial IPython.kernel |
|
114 | trial IPython.kernel | |
44 |
|
115 | |||
45 | * For now, regular tests (of non-Twisted using code) should be written as |
|
|||
46 | unit tests. They should be subclasses of :class:`unittest.TestCase`. |
|
|||
47 |
|
116 | |||
48 | * Tests of Twisted [Twisted]_ using code should be written by subclassing the |
|
117 | For developers: writing tests | |
49 | ``TestCase`` class that comes with ``twisted.trial.unittest``. Furthermore, |
|
118 | ============================= | |
50 | all :class:`Deferred` instances that are created in the test must be |
|
119 | ||
51 | properly chained and the final one *must* be the return value of the test |
|
120 | By now IPython has a reasonable test suite, so the best way to see what's | |
52 | method. |
|
121 | available is to look at the :file:`tests` directory in most subpackages. But | |
|
122 | here are a few pointers to make the process easier. | |||
|
123 | ||||
|
124 | ||||
|
125 | Main tools: :mod:`IPython.testing` | |||
|
126 | ---------------------------------- | |||
|
127 | ||||
|
128 | The :mod:`IPython.testing` package is where all of the machinery to test | |||
|
129 | IPython (rather than the tests for its various parts) lives. In particular, | |||
|
130 | the :mod:`iptest` module in there has all the smarts to control the test | |||
|
131 | process. In there, the :func:`make_exclude` function is used to build a | |||
|
132 | blacklist of exclusions, these are modules that do not get even imported for | |||
|
133 | tests. This is important so that things that would fail to even import because | |||
|
134 | of missing dependencies don't give errors to end users, as we stated above. | |||
|
135 | ||||
|
136 | The :mod:`decorators` module contains a lot of useful decorators, especially | |||
|
137 | useful to mark individual tests that should be skipped under certain conditions | |||
|
138 | (rather than blacklisting the package altogether because of a missing major | |||
|
139 | dependency). | |||
|
140 | ||||
|
141 | Our nose plugin for doctests | |||
|
142 | ---------------------------- | |||
|
143 | ||||
|
144 | The :mod:`plugin` subpackage in testing contains a nose plugin called | |||
|
145 | :mod:`ipdoctest` that teaches nose about IPython syntax, so you can write | |||
|
146 | doctests with IPython prompts. You can also mark doctest output with ``# | |||
|
147 | random`` for the output corresponding to a single input to be ignored (stronger | |||
|
148 | than using ellipsis and useful to keep it as an example). If you want the | |||
|
149 | entire docstring to be executed but none of the output from any input to be | |||
|
150 | checked, you can use the ``# all-random`` marker. The | |||
|
151 | :mod:`IPython.testing.plugin.dtexample` module contains examples of how to use | |||
|
152 | these; for reference here is how to use ``# random``:: | |||
|
153 | ||||
|
154 | def ranfunc(): | |||
|
155 | """A function with some random output. | |||
|
156 | ||||
|
157 | Normal examples are verified as usual: | |||
|
158 | >>> 1+3 | |||
|
159 | 4 | |||
|
160 | ||||
|
161 | But if you put '# random' in the output, it is ignored: | |||
|
162 | >>> 1+3 | |||
|
163 | junk goes here... # random | |||
|
164 | ||||
|
165 | >>> 1+2 | |||
|
166 | again, anything goes #random | |||
|
167 | if multiline, the random mark is only needed once. | |||
|
168 | ||||
|
169 | >>> 1+2 | |||
|
170 | You can also put the random marker at the end: | |||
|
171 | # random | |||
|
172 | ||||
|
173 | >>> 1+2 | |||
|
174 | # random | |||
|
175 | .. or at the beginning. | |||
|
176 | ||||
|
177 | More correct input is properly verified: | |||
|
178 | >>> ranfunc() | |||
|
179 | 'ranfunc' | |||
|
180 | """ | |||
|
181 | return 'ranfunc' | |||
|
182 | ||||
|
183 | and an example of ``# all-random``:: | |||
|
184 | ||||
|
185 | def random_all(): | |||
|
186 | """A function where we ignore the output of ALL examples. | |||
|
187 | ||||
|
188 | Examples: | |||
|
189 | ||||
|
190 | # all-random | |||
|
191 | ||||
|
192 | This mark tells the testing machinery that all subsequent examples | |||
|
193 | should be treated as random (ignoring their output). They are still | |||
|
194 | executed, so if a they raise an error, it will be detected as such, | |||
|
195 | but their output is completely ignored. | |||
|
196 | ||||
|
197 | >>> 1+3 | |||
|
198 | junk goes here... | |||
|
199 | ||||
|
200 | >>> 1+3 | |||
|
201 | klasdfj; | |||
|
202 | ||||
|
203 | In [8]: print 'hello' | |||
|
204 | world # random | |||
|
205 | ||||
|
206 | In [9]: iprand() | |||
|
207 | Out[9]: 'iprand' | |||
|
208 | """ | |||
|
209 | return 'iprand' | |||
|
210 | ||||
|
211 | ||||
|
212 | When writing docstrings, you can use the ``@skip_doctest`` decorator to | |||
|
213 | indicate that a docstring should *not* be treated as a doctest at all. The | |||
|
214 | difference betwee ``# all-random`` and ``@skip_doctest`` is that the former | |||
|
215 | executes the example but ignores output, while the latter doesn't execute any | |||
|
216 | code. ``@skip_doctest`` should be used for docstrings whose examples are | |||
|
217 | purely informational. | |||
|
218 | ||||
|
219 | If a given docstring fails under certain conditions but otherwise is a good | |||
|
220 | doctest, you can use code like the following, that relies on the 'null' | |||
|
221 | decorator to leave the docstring intact where it works as a test:: | |||
|
222 | ||||
|
223 | # The docstring for full_path doctests differently on win32 (different path | |||
|
224 | # separator) so just skip the doctest there, and use a null decorator | |||
|
225 | # elsewhere: | |||
|
226 | ||||
|
227 | doctest_deco = dec.skip_doctest if sys.platform == 'win32' else dec.null_deco | |||
|
228 | ||||
|
229 | @doctest_deco | |||
|
230 | def full_path(startPath,files): | |||
|
231 | """Make full paths for all the listed files, based on startPath...""" | |||
|
232 | ||||
|
233 | # function body follows... | |||
|
234 | ||||
|
235 | With our nose plugin that understands IPython syntax, an extremely effective | |||
|
236 | way to write tests is to simply copy and paste an interactive session into a | |||
|
237 | docstring. You can writing this type of test, where your docstring is meant | |||
|
238 | *only* as a test, by prefixing the function name with ``doctest_`` and leaving | |||
|
239 | its body *absolutely empty* other than the docstring. In | |||
|
240 | :mod:`IPython.core.tests.test_magic` you can find several examples of this, but | |||
|
241 | for completeness sake, your code should look like this (a simple case):: | |||
|
242 | ||||
|
243 | def doctest_time(): | |||
|
244 | """ | |||
|
245 | In [10]: %time None | |||
|
246 | CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s | |||
|
247 | Wall time: 0.00 s | |||
|
248 | """ | |||
|
249 | ||||
|
250 | This function is only analyzed for its docstring but it is not considered a | |||
|
251 | separate test, which is why its body should be empty. | |||
|
252 | ||||
|
253 | ||||
|
254 | Parametric tests done right | |||
|
255 | --------------------------- | |||
|
256 | ||||
|
257 | If you need to run multiple tests inside the same standalone function or method | |||
|
258 | of a :class:`unittest.TestCase` subclass, IPython provides the ``parametric`` | |||
|
259 | decorator for this purpose. This is superior to how test generators work in | |||
|
260 | nose, because IPython's keeps intact your stack, which makes debugging vastly | |||
|
261 | easier. For example, these are some parametric tests both in class form and as | |||
|
262 | a standalone function (choose in each situation the style that best fits the | |||
|
263 | problem at hand, since both work):: | |||
|
264 | ||||
|
265 | from IPython.testing import decorators as dec | |||
|
266 | ||||
|
267 | def is_smaller(i,j): | |||
|
268 | assert i<j,"%s !< %s" % (i,j) | |||
|
269 | ||||
|
270 | class Tester(ParametricTestCase): | |||
|
271 | ||||
|
272 | def test_parametric(self): | |||
|
273 | yield is_smaller(3, 4) | |||
|
274 | x, y = 1, 2 | |||
|
275 | yield is_smaller(x, y) | |||
|
276 | ||||
|
277 | @dec.parametric | |||
|
278 | def test_par_standalone(): | |||
|
279 | yield is_smaller(3, 4) | |||
|
280 | x, y = 1, 2 | |||
|
281 | yield is_smaller(x, y) | |||
|
282 | ||||
|
283 | ||||
|
284 | Writing tests for Twisted-using code | |||
|
285 | ------------------------------------ | |||
|
286 | ||||
|
287 | Tests of Twisted [Twisted]_ using code should be written by subclassing the | |||
|
288 | ``TestCase`` class that comes with ``twisted.trial.unittest``. Furthermore, all | |||
|
289 | :class:`Deferred` instances that are created in the test must be properly | |||
|
290 | chained and the final one *must* be the return value of the test method. | |||
|
291 | ||||
|
292 | .. note:: | |||
|
293 | ||||
|
294 | The best place to see how to use the testing tools, are the tests for these | |||
|
295 | tools themselves, which live in :mod:`IPython.testing.tests`. | |||
|
296 | ||||
|
297 | ||||
|
298 | Design requirements | |||
|
299 | =================== | |||
|
300 | ||||
|
301 | This section is a set of notes on the key points of the IPython testing needs, | |||
|
302 | that were used when writing the system and should be kept for reference as it | |||
|
303 | eveolves. | |||
|
304 | ||||
|
305 | Testing IPython in full requires modifications to the default behavior of nose | |||
|
306 | and doctest, because the IPython prompt is not recognized to determine Python | |||
|
307 | input, and because IPython admits user input that is not valid Python (things | |||
|
308 | like ``%magics`` and ``!system commands``. | |||
|
309 | ||||
|
310 | We basically need to be able to test the following types of code: | |||
|
311 | ||||
|
312 | 1. Pure Python files containing normal tests. These are not a problem, since | |||
|
313 | Nose will pick them up as long as they conform to the (flexible) conventions | |||
|
314 | used by nose to recognize tests. | |||
|
315 | ||||
|
316 | 2. Python files containing doctests. Here, we have two possibilities: | |||
|
317 | - The prompts are the usual ``>>>`` and the input is pure Python. | |||
|
318 | - The prompts are of the form ``In [1]:`` and the input can contain extended | |||
|
319 | IPython expressions. | |||
|
320 | ||||
|
321 | In the first case, Nose will recognize the doctests as long as it is called | |||
|
322 | with the ``--with-doctest`` flag. But the second case will likely require | |||
|
323 | modifications or the writing of a new doctest plugin for Nose that is | |||
|
324 | IPython-aware. | |||
|
325 | ||||
|
326 | 3. ReStructuredText files that contain code blocks. For this type of file, we | |||
|
327 | have three distinct possibilities for the code blocks: | |||
|
328 | - They use ``>>>`` prompts. | |||
|
329 | - They use ``In [1]:`` prompts. | |||
|
330 | - They are standalone blocks of pure Python code without any prompts. | |||
|
331 | ||||
|
332 | The first two cases are similar to the situation #2 above, except that in | |||
|
333 | this case the doctests must be extracted from input code blocks using | |||
|
334 | docutils instead of from the Python docstrings. | |||
|
335 | ||||
|
336 | In the third case, we must have a convention for distinguishing code blocks | |||
|
337 | that are meant for execution from others that may be snippets of shell code | |||
|
338 | or other examples not meant to be run. One possibility is to assume that | |||
|
339 | all indented code blocks are meant for execution, but to have a special | |||
|
340 | docutils directive for input that should not be executed. | |||
|
341 | ||||
|
342 | For those code blocks that we will execute, the convention used will simply | |||
|
343 | be that they get called and are considered successful if they run to | |||
|
344 | completion without raising errors. This is similar to what Nose does for | |||
|
345 | standalone test functions, and by putting asserts or other forms of | |||
|
346 | exception-raising statements it becomes possible to have literate examples | |||
|
347 | that double as lightweight tests. | |||
|
348 | ||||
|
349 | 4. Extension modules with doctests in function and method docstrings. | |||
|
350 | Currently Nose simply can't find these docstrings correctly, because the | |||
|
351 | underlying doctest DocTestFinder object fails there. Similarly to #2 above, | |||
|
352 | the docstrings could have either pure python or IPython prompts. | |||
53 |
|
353 | |||
54 | .. [Nose] Nose: a discovery based unittest extension. http://code.google.com/p/python-nose/ |
|
354 | Of these, only 3-c (reST with standalone code blocks) is not implemented at | |
|
355 | this point. |
General Comments 0
You need to be logged in to leave comments.
Login now