5 :Authors: Lea Wiemann <LeWiemann@gmail.com>;
6 David Goodger <goodger@python.org>
9 :Copyright: This document has been placed in the public domain.
11 .. _Docutils: http://docutils.sourceforge.net/
15 When adding new functionality (or fixing bugs), be sure to add test
16 cases to the test suite. Practise test-first programming; it's fun,
17 it's addictive, and it works!
19 This document describes how to run the Docutils test suite, how the
20 tests are organized and how to add new tests or modify existing tests.
23 Running the Test Suite
24 ======================
26 Before checking in any changes, run the entire Docutils test suite to
27 be sure that you haven't broken anything. From a shell::
36 The Docutils 0.10 release supports Python 2.4 or later. Therefore, you should
37 actually have Pythons 2.4, as well as the latest Python (3.2 at the time
38 of this writing) installed and always run the tests on all of them. (A good
39 way to do that is to always run the test suite through a short script that
40 runs ``alltests.py`` under each version of Python.) If you can't afford
41 installing 3 or more Python versions, the edge cases (2.4, and 3.2) should
44 Good resources covering the differences between Python versions:
46 * `What's New in Python 2.4`__
47 * `What's New in Python 2.5`__
48 * `What's New in Python 2.6`__
49 * `PEP 290 - Code Migration and Modernization`__
51 __ http://www.python.org/doc/2.4.4/whatsnew/whatsnew24.html
52 __ http://www.python.org/doc/2.5.2/whatsnew/whatsnew25.html
53 __ http://docs.python.org/whatsnew/2.6.html
54 __ http://www.python.org/peps/pep-0290.html
56 .. _Python Check-in Policies: http://www.python.org/dev/tools.html
57 .. _sandbox directory:
58 http://docutils.svn.sourceforge.net/svnroot/docutils/trunk/sandbox/
59 .. _nightly repository tarball:
60 http://svn.berlios.de/svndumps/docutils-repos.gz
66 Unit tests test single functions or modules (i.e. whitebox testing).
68 If you are implementing a new feature, be sure to write a test case
69 covering its functionality. It happens very frequently that your
70 implementation (or even only a part of it) doesn't work with an older
71 (or even newer) Python version, and the only reliable way to detect
72 those cases is using tests.
74 Often, it's easier to write the test first and then implement the
75 functionality required to make the test pass.
81 When writing new tests, it very often helps to see how a similar test
82 is implemented. For example, the files in the
83 ``test_parsers/test_rst/`` directory all look very similar. So when
84 adding a test, you don't have to reinvent the wheel.
86 If there is no similar test, you can write a new test from scratch
87 using Python's ``unittest`` module. For an example, please have a
88 look at the following imaginary ``test_square.py``::
90 #! /usr/bin/env python
93 # Author: Your Name <your_email_address@example.org>
94 # Copyright: This module has been placed in the public domain.
97 Test module for docutils.square.
101 import docutils.square
104 class SquareTest(unittest.TestCase):
106 def test_square(self):
107 self.assertEqual(docutils.square.square(0), 0)
108 self.assertEqual(docutils.square.square(5), 25)
109 self.assertEqual(docutils.square.square(7), 49)
111 def test_square_root(self):
112 self.assertEqual(docutils.square.sqrt(49), 7)
113 self.assertEqual(docutils.square.sqrt(0), 0)
114 self.assertRaises(docutils.square.SquareRootError,
115 docutils.square.sqrt, 20)
118 if __name__ == '__main__':
121 For more details on how to write tests, please refer to the
122 documentation of the ``unittest`` module.
130 The directory ``test/functional/`` contains data for functional tests.
132 Performing functional testing means testing the Docutils system as a
133 whole (i.e. blackbox testing).
139 + ``functional/`` The main data directory.
141 + ``input/`` The input files.
143 - ``some_test.txt``, for example.
145 + ``output/`` The actual output.
147 - ``some_test.html``, for example.
149 + ``expected/`` The expected output.
151 - ``some_test.html``, for example.
153 + ``tests/`` The config files for processing the input files.
155 - ``some_test.py``, for example.
157 - ``_default.py``, the `default configuration file`_.
163 When running ``test_functional.py``, all config files in
164 ``functional/tests/`` are processed. (Config files whose names begin
165 with an underscore are ignored.) The current working directory is
166 always Docutils' main test directory (``test/``).
168 For example, ``functional/tests/some_test.py`` could read like this::
170 # Source and destination file names.
171 test_source = "some_test.txt"
172 test_destination = "some_test.html"
174 # Keyword parameters passed to publish_file.
175 reader_name = "standalone"
178 settings_overrides['output-encoding'] = 'utf-8'
179 # Relative to main ``test/`` directory.
180 settings_overrides['stylesheet_path'] = '../docutils/writers/html4css1/html4css1.css'
182 The two variables ``test_source`` and ``test_destination`` contain the
183 input file name (relative to ``functional/input/``) and the output
184 file name (relative to ``functional/output/`` and
185 ``functional/expected/``). Note that the file names can be chosen
186 arbitrarily. However, the file names in ``functional/output/`` *must*
187 match the file names in ``functional/expected/``.
189 If defined, ``_test_more`` must be a function with the following
192 def _test_more(expected_dir, output_dir, test_case, parameters):
194 This function is called from the test case to perform tests beyond the
195 simple comparison of expected and actual output files.
197 ``test_source`` and ``test_destination`` are removed from the
198 namespace, as are all variables whose names begin with an underscore
199 ("_"). The remaining names are passed as keyword arguments to
200 ``docutils.core.publish_file``, so you can set reader, parser, writer
201 and anything else you want to configure. Note that
202 ``settings_overrides`` is already initialized as a dictionary *before*
203 the execution of the config file.
209 In order to create a new test, put the input test file into
210 ``functional/input/``. Then create a config file in
211 ``functional/tests/`` which sets at least input and output file names,
212 reader, parser and writer.
214 Now run ``test_functional.py``. The test will fail, of course,
215 because you do not have an expected output yet. However, an output
216 file will have been generated in ``functional/output/``. Check this
217 output file for validity and correctness. Then copy the file to
218 ``functional/expected/``.
220 If you rerun ``test_functional.py`` now, it should pass.
222 If you run ``test_functional.py`` later and the actual output doesn't
223 match the expected output anymore, the test will fail.
225 If this is the case and you made an intentional change, check the
226 actual output for validity and correctness, copy it to
227 ``functional/expected/`` (overwriting the old expected output), and
231 .. _default configuration file:
233 The Default Configuration File
234 ------------------------------
236 The file ``functional/tests/_default.py`` contains default settings.
237 It is executed just before the actual configuration files, which has
238 the same effect as if the contents of ``_default.py`` were prepended
239 to every configuration file.