4634.39.32
by Ian Clatworthy
proper Contents panel in bzr-developers.chm |
1 |
==================== |
2 |
Bazaar Testing Guide |
|
3 |
==================== |
|
3619.3.1
by Andrew Bennetts
Move the notes on writing tests out of HACKING into a new file, and improve |
4 |
|
5 |
||
6 |
The Importance of Testing |
|
7 |
========================= |
|
8 |
||
5225.2.1
by Martin Pool
Mention Babune in test guide. |
9 |
Reliability is a critical success factor for any version control system. |
3619.3.1
by Andrew Bennetts
Move the notes on writing tests out of HACKING into a new file, and improve |
10 |
We want Bazaar to be highly reliable across multiple platforms while |
11 |
evolving over time to meet the needs of its community. |
|
12 |
||
13 |
In a nutshell, this is what we expect and encourage: |
|
14 |
||
15 |
* New functionality should have test cases. Preferably write the |
|
16 |
test before writing the code. |
|
17 |
||
18 |
In general, you can test at either the command-line level or the |
|
19 |
internal API level. See `Writing tests`_ below for more detail. |
|
20 |
||
21 |
* Try to practice Test-Driven Development: before fixing a bug, write a |
|
22 |
test case so that it does not regress. Similarly for adding a new |
|
23 |
feature: write a test case for a small version of the new feature before |
|
24 |
starting on the code itself. Check the test fails on the old code, then |
|
25 |
add the feature or fix and check it passes. |
|
26 |
||
27 |
By doing these things, the Bazaar team gets increased confidence that |
|
28 |
changes do what they claim to do, whether provided by the core team or |
|
29 |
by community members. Equally importantly, we can be surer that changes |
|
30 |
down the track do not break new features or bug fixes that you are |
|
31 |
contributing today. |
|
32 |
||
4665.2.2
by Martin Pool
Doc update that there are actually many more tests now |
33 |
As of September 2009, Bazaar ships with a test suite containing over |
34 |
23,000 tests and growing. We are proud of it and want to remain so. As |
|
35 |
community members, we all benefit from it. Would you trust version control |
|
36 |
on your project to a product *without* a test suite like Bazaar has? |
|
3619.3.1
by Andrew Bennetts
Move the notes on writing tests out of HACKING into a new file, and improve |
37 |
|
38 |
||
39 |
Running the Test Suite |
|
40 |
====================== |
|
41 |
||
5004.2.5
by Martin Pool
More docs on testing |
42 |
As of Bazaar 2.1, you must have the testtools_ library installed to run |
43 |
the bzr test suite. |
|
44 |
||
45 |
.. _testtools: https://launchpad.net/testtools/ |
|
46 |
||
5004.2.4
by Martin Pool
More tips on running tests |
47 |
To test all of Bazaar, just run:: |
48 |
||
49 |
bzr selftest |
|
50 |
||
5004.2.5
by Martin Pool
More docs on testing |
51 |
With ``--verbose`` bzr will print the name of every test as it is run. |
52 |
||
5004.2.4
by Martin Pool
More tips on running tests |
53 |
This should always pass, whether run from a source tree or an installed |
54 |
copy of Bazaar. Please investigate and/or report any failures. |
|
55 |
||
56 |
||
57 |
Running particular tests |
|
58 |
------------------------ |
|
59 |
||
3619.3.1
by Andrew Bennetts
Move the notes on writing tests out of HACKING into a new file, and improve |
60 |
Currently, bzr selftest is used to invoke tests. |
61 |
You can provide a pattern argument to run a subset. For example, |
|
62 |
to run just the blackbox tests, run:: |
|
63 |
||
64 |
./bzr selftest -v blackbox |
|
65 |
||
66 |
To skip a particular test (or set of tests), use the --exclude option |
|
67 |
(shorthand -x) like so:: |
|
68 |
||
69 |
./bzr selftest -v -x blackbox |
|
70 |
||
71 |
To ensure that all tests are being run and succeeding, you can use the |
|
72 |
--strict option which will fail if there are any missing features or known |
|
73 |
failures, like so:: |
|
74 |
||
75 |
./bzr selftest --strict |
|
76 |
||
77 |
To list tests without running them, use the --list-only option like so:: |
|
78 |
||
79 |
./bzr selftest --list-only |
|
80 |
||
81 |
This option can be combined with other selftest options (like -x) and |
|
82 |
filter patterns to understand their effect. |
|
83 |
||
84 |
Once you understand how to create a list of tests, you can use the --load-list |
|
85 |
option to run only a restricted set of tests that you kept in a file, one test |
|
86 |
id by line. Keep in mind that this will never be sufficient to validate your |
|
87 |
modifications, you still need to run the full test suite for that, but using it |
|
88 |
can help in some cases (like running only the failed tests for some time):: |
|
89 |
||
90 |
./bzr selftest -- load-list my_failing_tests |
|
91 |
||
92 |
This option can also be combined with other selftest options, including |
|
93 |
patterns. It has some drawbacks though, the list can become out of date pretty |
|
94 |
quick when doing Test Driven Development. |
|
95 |
||
96 |
To address this concern, there is another way to run a restricted set of tests: |
|
97 |
the --starting-with option will run only the tests whose name starts with the |
|
98 |
specified string. It will also avoid loading the other tests and as a |
|
99 |
consequence starts running your tests quicker:: |
|
100 |
||
101 |
./bzr selftest --starting-with bzrlib.blackbox |
|
102 |
||
103 |
This option can be combined with all the other selftest options including |
|
104 |
--load-list. The later is rarely used but allows to run a subset of a list of |
|
105 |
failing tests for example. |
|
106 |
||
5004.2.4
by Martin Pool
More tips on running tests |
107 |
Disabling plugins |
108 |
----------------- |
|
109 |
||
110 |
To test only the bzr core, ignoring any plugins you may have installed, |
|
111 |
use:: |
|
112 |
||
113 |
./bzr --no-plugins selftest |
|
3619.3.1
by Andrew Bennetts
Move the notes on writing tests out of HACKING into a new file, and improve |
114 |
|
5004.2.2
by Martin Pool
Recommend using -Dno_apport for development |
115 |
Disabling crash reporting |
116 |
------------------------- |
|
117 |
||
118 |
By default Bazaar uses apport_ to report program crashes. In developing |
|
119 |
Bazaar it's normal and expected to have it crash from time to time, at |
|
120 |
least because a test failed if for no other reason. |
|
121 |
||
122 |
Therefore you should probably add ``debug_flags = no_apport`` to your |
|
123 |
``bazaar.conf`` file (in ``~/.bazaar/`` on Unix), so that failures just |
|
124 |
print a traceback rather than writing a crash file. |
|
125 |
||
126 |
.. _apport: https://launchpad.net/apport/ |
|
127 |
||
128 |
||
3619.3.1
by Andrew Bennetts
Move the notes on writing tests out of HACKING into a new file, and improve |
129 |
Test suite debug flags |
130 |
---------------------- |
|
131 |
||
132 |
Similar to the global ``-Dfoo`` debug options, bzr selftest accepts |
|
133 |
``-E=foo`` debug flags. These flags are: |
|
134 |
||
135 |
:allow_debug: do *not* clear the global debug flags when running a test. |
|
136 |
This can provide useful logging to help debug test failures when used |
|
137 |
with e.g. ``bzr -Dhpss selftest -E=allow_debug`` |
|
138 |
||
5004.2.3
by Martin Pool
Caveat on -Eallow_debug |
139 |
Note that this will probably cause some tests to fail, because they |
140 |
don't expect to run with any debug flags on. |
|
141 |
||
3619.3.1
by Andrew Bennetts
Move the notes on writing tests out of HACKING into a new file, and improve |
142 |
|
5004.2.5
by Martin Pool
More docs on testing |
143 |
Using subunit |
144 |
------------- |
|
145 |
||
146 |
Bazaar can optionally produce output in the machine-readable subunit_ |
|
5060.2.1
by Robert Collins
* bzr now has a ``.testr.conf`` file in its source tree configured |
147 |
format, so that test output can be post-processed by various tools. To |
148 |
generate a subunit test stream:: |
|
149 |
||
150 |
$ ./bzr selftest --subunit |
|
151 |
||
152 |
Processing such a stream can be done using a variety of tools including: |
|
153 |
||
154 |
* The builtin ``subunit2pyunit``, ``subunit-filter``, ``subunit-ls``, |
|
155 |
``subunit2junitxml`` from the subunit project. |
|
156 |
||
157 |
* tribunal_, a GUI for showing test results. |
|
158 |
||
159 |
* testrepository_, a tool for gathering and managing test runs. |
|
5004.2.5
by Martin Pool
More docs on testing |
160 |
|
161 |
.. _subunit: https://launchpad.net/subunit/ |
|
5060.2.1
by Robert Collins
* bzr now has a ``.testr.conf`` file in its source tree configured |
162 |
.. _tribunal: https://launchpad.net/tribunal/ |
163 |
||
164 |
||
165 |
Using testrepository |
|
166 |
-------------------- |
|
167 |
||
168 |
Bazaar ships with a config file for testrepository_. This can be very |
|
169 |
useful for keeping track of failing tests and doing general workflow |
|
170 |
support. To run tests using testrepository:: |
|
171 |
||
172 |
$ testr run |
|
173 |
||
174 |
To run only failing tests:: |
|
175 |
||
176 |
$ testr run --failing |
|
177 |
||
178 |
To run only some tests, without plugins:: |
|
179 |
||
180 |
$ test run test_selftest -- --no-plugins |
|
181 |
||
182 |
See the testrepository documentation for more details. |
|
183 |
||
184 |
.. _testrepository: https://launchpad.net/testrepository |
|
5004.2.5
by Martin Pool
More docs on testing |
185 |
|
5225.2.1
by Martin Pool
Mention Babune in test guide. |
186 |
|
187 |
Babune continuous integration |
|
188 |
----------------------------- |
|
189 |
||
190 |
We have a Hudson continuous-integration system that automatically runs |
|
191 |
tests across various platforms. In the future we plan to add more |
|
192 |
combinations including testing plugins. See |
|
193 |
<http://babune.ladeuil.net:24842/>. (Babune = Bazaar Buildbot Network.) |
|
194 |
||
195 |
||
5335.3.2
by Martin Pool
Note about selftest --parallel |
196 |
Running tests in parallel |
197 |
------------------------- |
|
198 |
||
199 |
Bazaar can use subunit to spawn multiple test processes. There is |
|
200 |
slightly more chance you will hit ordering or timing-dependent bugs but |
|
201 |
it's much faster:: |
|
202 |
||
203 |
$ ./bzr selftest --parallel=fork |
|
204 |
||
5335.3.4
by Martin Pool
Review tweaks to testing documentation |
205 |
Note that you will need the Subunit library |
206 |
<https://launchpad.net/subunit/> to use this, which is in |
|
207 |
``python-subunit`` on Ubuntu. |
|
208 |
||
5335.3.2
by Martin Pool
Note about selftest --parallel |
209 |
|
5335.3.1
by Martin Pool
notes on testing on a tmpfs |
210 |
Running tests from a ramdisk |
211 |
---------------------------- |
|
212 |
||
213 |
The tests create and delete a lot of temporary files. In some cases you |
|
214 |
can make the test suite run much faster by running it on a ramdisk. For |
|
215 |
example:: |
|
216 |
||
217 |
$ sudo mkdir /ram |
|
218 |
$ sudo mount -t tmpfs none /ram |
|
219 |
$ TMPDIR=/ram ./bzr selftest ... |
|
220 |
||
221 |
You could also change ``/tmp`` in ``/etc/fstab`` to have type ``tmpfs``, |
|
222 |
if you don't mind possibly losing other files in there when the machine |
|
5335.3.4
by Martin Pool
Review tweaks to testing documentation |
223 |
restarts. Add this line (if there is none for ``/tmp`` already):: |
224 |
||
225 |
none /tmp tmpfs defaults 0 0 |
|
5335.3.1
by Martin Pool
notes on testing on a tmpfs |
226 |
|
227 |
With a 6-core machine and ``--parallel=fork`` using a tmpfs doubles the |
|
228 |
test execution speed. |
|
229 |
||
230 |
||
3619.3.1
by Andrew Bennetts
Move the notes on writing tests out of HACKING into a new file, and improve |
231 |
Writing Tests |
232 |
============= |
|
233 |
||
5004.2.5
by Martin Pool
More docs on testing |
234 |
Normally you should add or update a test for all bug fixes or new features |
235 |
in Bazaar. |
|
236 |
||
237 |
||
3619.3.1
by Andrew Bennetts
Move the notes on writing tests out of HACKING into a new file, and improve |
238 |
Where should I put a new test? |
239 |
------------------------------ |
|
240 |
||
241 |
Bzrlib's tests are organised by the type of test. Most of the tests in |
|
242 |
bzr's test suite belong to one of these categories: |
|
243 |
||
244 |
- Unit tests |
|
245 |
- Blackbox (UI) tests |
|
246 |
- Per-implementation tests |
|
247 |
- Doctests |
|
248 |
||
249 |
A quick description of these test types and where they belong in bzrlib's |
|
250 |
source follows. Not all tests fall neatly into one of these categories; |
|
251 |
in those cases use your judgement. |
|
252 |
||
253 |
||
254 |
Unit tests |
|
255 |
~~~~~~~~~~ |
|
256 |
||
257 |
Unit tests make up the bulk of our test suite. These are tests that are |
|
258 |
focused on exercising a single, specific unit of the code as directly |
|
259 |
as possible. Each unit test is generally fairly short and runs very |
|
260 |
quickly. |
|
261 |
||
262 |
They are found in ``bzrlib/tests/test_*.py``. So in general tests should |
|
263 |
be placed in a file named test_FOO.py where FOO is the logical thing under |
|
264 |
test. |
|
265 |
||
266 |
For example, tests for merge3 in bzrlib belong in bzrlib/tests/test_merge3.py. |
|
267 |
See bzrlib/tests/test_sampler.py for a template test script. |
|
268 |
||
269 |
||
270 |
Blackbox (UI) tests |
|
271 |
~~~~~~~~~~~~~~~~~~~ |
|
272 |
||
273 |
Tests can be written for the UI or for individual areas of the library. |
|
274 |
Choose whichever is appropriate: if adding a new command, or a new command |
|
275 |
option, then you should be writing a UI test. If you are both adding UI |
|
276 |
functionality and library functionality, you will want to write tests for |
|
277 |
both the UI and the core behaviours. We call UI tests 'blackbox' tests |
|
278 |
and they belong in ``bzrlib/tests/blackbox/*.py``. |
|
279 |
||
280 |
When writing blackbox tests please honour the following conventions: |
|
281 |
||
282 |
1. Place the tests for the command 'name' in |
|
283 |
bzrlib/tests/blackbox/test_name.py. This makes it easy for developers |
|
284 |
to locate the test script for a faulty command. |
|
285 |
||
286 |
2. Use the 'self.run_bzr("name")' utility function to invoke the command |
|
287 |
rather than running bzr in a subprocess or invoking the |
|
288 |
cmd_object.run() method directly. This is a lot faster than |
|
289 |
subprocesses and generates the same logging output as running it in a |
|
290 |
subprocess (which invoking the method directly does not). |
|
4853.1.1
by Patrick Regan
Removed trailing whitespace from files in doc directory |
291 |
|
3619.3.1
by Andrew Bennetts
Move the notes on writing tests out of HACKING into a new file, and improve |
292 |
3. Only test the one command in a single test script. Use the bzrlib |
293 |
library when setting up tests and when evaluating the side-effects of |
|
294 |
the command. We do this so that the library api has continual pressure |
|
295 |
on it to be as functional as the command line in a simple manner, and |
|
296 |
to isolate knock-on effects throughout the blackbox test suite when a |
|
297 |
command changes its name or signature. Ideally only the tests for a |
|
298 |
given command are affected when a given command is changed. |
|
299 |
||
300 |
4. If you have a test which does actually require running bzr in a |
|
301 |
subprocess you can use ``run_bzr_subprocess``. By default the spawned |
|
302 |
process will not load plugins unless ``--allow-plugins`` is supplied. |
|
303 |
||
304 |
||
305 |
Per-implementation tests |
|
306 |
~~~~~~~~~~~~~~~~~~~~~~~~ |
|
307 |
||
308 |
Per-implementation tests are tests that are defined once and then run |
|
309 |
against multiple implementations of an interface. For example, |
|
4913.3.7
by John Arbash Meinel
Doc updates for permute_for_extension |
310 |
``per_transport.py`` defines tests that all Transport implementations |
311 |
(local filesystem, HTTP, and so on) must pass. They are found in |
|
312 |
``bzrlib/tests/per_*/*.py``, and ``bzrlib/tests/per_*.py``. |
|
3619.3.1
by Andrew Bennetts
Move the notes on writing tests out of HACKING into a new file, and improve |
313 |
|
314 |
These are really a sub-category of unit tests, but an important one. |
|
315 |
||
4913.3.7
by John Arbash Meinel
Doc updates for permute_for_extension |
316 |
Along the same lines are tests for extension modules. We generally have |
317 |
both a pure-python and a compiled implementation for each module. As such, |
|
318 |
we want to run the same tests against both implementations. These can |
|
319 |
generally be found in ``bzrlib/tests/*__*.py`` since extension modules are |
|
320 |
usually prefixed with an underscore. Since there are only two |
|
321 |
implementations, we have a helper function |
|
322 |
``bzrlib.tests.permute_for_extension``, which can simplify the |
|
323 |
``load_tests`` implementation. |
|
324 |
||
3619.3.1
by Andrew Bennetts
Move the notes on writing tests out of HACKING into a new file, and improve |
325 |
|
326 |
Doctests |
|
327 |
~~~~~~~~ |
|
328 |
||
329 |
We make selective use of doctests__. In general they should provide |
|
330 |
*examples* within the API documentation which can incidentally be tested. We |
|
5193.5.8
by Vincent Ladeuil
Revert previous change as I can't reproduce the related problem anymore. |
331 |
don't try to test every important case using doctests |--| regular Python |
5574.6.9
by Vincent Ladeuil
Add a warning about doctest isolation in the developer doc. |
332 |
tests are generally a better solution. That is, we just use doctests to make |
333 |
our documentation testable, rather than as a way to make tests. Be aware that |
|
334 |
doctests are not as well isolated as the unit tests, if you need more |
|
335 |
isolation, you're likely want to write unit tests anyway if only to get a |
|
336 |
better control of the test environment. |
|
3619.3.1
by Andrew Bennetts
Move the notes on writing tests out of HACKING into a new file, and improve |
337 |
|
338 |
Most of these are in ``bzrlib/doc/api``. More additions are welcome. |
|
339 |
||
340 |
__ http://docs.python.org/lib/module-doctest.html |
|
341 |
||
5609.28.1
by Martin Pool
Add assertDoctestExampleMatches |
342 |
There is an `assertDoctestExampleMatches` method in |
343 |
`bzrlib.tests.TestCase` that allows you to match against doctest-style |
|
344 |
string templates (including ``...`` to skip sections) from regular Python |
|
345 |
tests. |
|
346 |
||
3619.3.1
by Andrew Bennetts
Move the notes on writing tests out of HACKING into a new file, and improve |
347 |
|
4665.5.20
by Vincent Ladeuil
Fixed as per Martin's review. |
348 |
Shell-like tests |
4917.2.1
by Martin Pool
Add better example for ScriptRunner and tweak its place in the document hierarchy |
349 |
---------------- |
4665.5.20
by Vincent Ladeuil
Fixed as per Martin's review. |
350 |
|
5455.1.2
by Vincent Ladeuil
More docs. |
351 |
``bzrlib/tests/script.py`` allows users to write tests in a syntax very |
352 |
close to a shell session, using a restricted and limited set of commands |
|
353 |
that should be enough to mimic most of the behaviours. |
|
4665.5.20
by Vincent Ladeuil
Fixed as per Martin's review. |
354 |
|
355 |
A script is a set of commands, each command is composed of: |
|
356 |
||
357 |
* one mandatory command line, |
|
358 |
* one optional set of input lines to feed the command, |
|
359 |
* one optional set of output expected lines, |
|
360 |
* one optional set of error expected lines. |
|
361 |
||
362 |
Input, output and error lines can be specified in any order. |
|
363 |
||
364 |
Except for the expected output, all lines start with a special |
|
365 |
string (based on their origin when used under a Unix shell): |
|
366 |
||
367 |
* '$ ' for the command, |
|
368 |
* '<' for input, |
|
369 |
* nothing for output, |
|
370 |
* '2>' for errors, |
|
371 |
||
372 |
Comments can be added anywhere, they start with '#' and end with |
|
373 |
the line. |
|
374 |
||
375 |
The execution stops as soon as an expected output or an expected error is not |
|
4853.1.1
by Patrick Regan
Removed trailing whitespace from files in doc directory |
376 |
matched. |
4665.5.20
by Vincent Ladeuil
Fixed as per Martin's review. |
377 |
|
5509.1.1
by Neil Martinsen-Burrell
add ignore_blanks to run_script to recover old behavior |
378 |
If output occurs and no output is expected, the execution stops and the |
379 |
test fails. If unexpected output occurs on the standard error, then |
|
5509.1.3
by Neil Martinsen-Burrell
change option name and mention the effect on standard error |
380 |
execution stops and the test fails. |
4665.5.20
by Vincent Ladeuil
Fixed as per Martin's review. |
381 |
|
382 |
If an error occurs and no expected error is specified, the execution stops. |
|
383 |
||
384 |
An error is defined by a returned status different from zero, not by the |
|
385 |
presence of text on the error stream. |
|
386 |
||
387 |
The matching is done on a full string comparison basis unless '...' is used, in |
|
388 |
which case expected output/errors can be less precise. |
|
389 |
||
390 |
Examples: |
|
391 |
||
392 |
The following will succeeds only if 'bzr add' outputs 'adding file':: |
|
393 |
||
394 |
$ bzr add file |
|
395 |
>adding file |
|
396 |
||
397 |
If you want the command to succeed for any output, just use:: |
|
398 |
||
399 |
$ bzr add file |
|
5422.3.3
by Martin Pool
Update ScriptRunner docs: blank won't match output; suggest -q |
400 |
... |
401 |
2>... |
|
402 |
||
403 |
or use the ``--quiet`` option:: |
|
404 |
||
405 |
$ bzr add -q file |
|
4665.5.20
by Vincent Ladeuil
Fixed as per Martin's review. |
406 |
|
407 |
The following will stop with an error:: |
|
408 |
||
409 |
$ bzr not-a-command |
|
410 |
||
411 |
If you want it to succeed, use:: |
|
412 |
||
413 |
$ bzr not-a-command |
|
414 |
2> bzr: ERROR: unknown command "not-a-command" |
|
415 |
||
416 |
You can use ellipsis (...) to replace any piece of text you don't want to be |
|
417 |
matched exactly:: |
|
418 |
||
419 |
$ bzr branch not-a-branch |
|
420 |
2>bzr: ERROR: Not a branch...not-a-branch/". |
|
421 |
||
422 |
This can be used to ignore entire lines too:: |
|
423 |
||
424 |
$ cat |
|
425 |
<first line |
|
426 |
<second line |
|
427 |
<third line |
|
428 |
# And here we explain that surprising fourth line |
|
429 |
<fourth line |
|
430 |
<last line |
|
431 |
>first line |
|
432 |
>... |
|
433 |
>last line |
|
434 |
||
435 |
You can check the content of a file with cat:: |
|
436 |
||
437 |
$ cat <file |
|
438 |
>expected content |
|
439 |
||
440 |
You can also check the existence of a file with cat, the following will fail if |
|
441 |
the file doesn't exist:: |
|
442 |
||
443 |
$ cat file |
|
444 |
||
5455.1.2
by Vincent Ladeuil
More docs. |
445 |
You can run files containing shell-like scripts with:: |
446 |
||
447 |
$ bzr test-script <script> |
|
448 |
||
449 |
where ``<script>`` is the path to the file containing the shell-like script. |
|
450 |
||
4917.2.1
by Martin Pool
Add better example for ScriptRunner and tweak its place in the document hierarchy |
451 |
The actual use of ScriptRunner within a TestCase looks something like |
452 |
this:: |
|
453 |
||
5283.1.1
by Martin Pool
Add helper function script.run_script and suggest using it |
454 |
from bzrlib.tests import script |
455 |
||
456 |
def test_unshelve_keep(self): |
|
457 |
# some setup here |
|
458 |
script.run_script(self, ''' |
|
5509.1.1
by Neil Martinsen-Burrell
add ignore_blanks to run_script to recover old behavior |
459 |
$ bzr add -q file |
460 |
$ bzr shelve -q --all -m Foo |
|
5283.1.1
by Martin Pool
Add helper function script.run_script and suggest using it |
461 |
$ bzr shelve --list |
462 |
1: Foo |
|
5509.1.1
by Neil Martinsen-Burrell
add ignore_blanks to run_script to recover old behavior |
463 |
$ bzr unshelve -q --keep |
5283.1.1
by Martin Pool
Add helper function script.run_script and suggest using it |
464 |
$ bzr shelve --list |
465 |
1: Foo |
|
466 |
$ cat file |
|
467 |
contents of file |
|
468 |
''') |
|
4917.2.1
by Martin Pool
Add better example for ScriptRunner and tweak its place in the document hierarchy |
469 |
|
5417.1.1
by Martin Pool
ScriptRunner can now cope with commands that prompt for input. |
470 |
You can also test commands that read user interaction:: |
471 |
||
472 |
def test_confirm_action(self): |
|
473 |
"""You can write tests that demonstrate user confirmation""" |
|
474 |
commands.builtin_command_registry.register(cmd_test_confirm) |
|
475 |
self.addCleanup(commands.builtin_command_registry.remove, 'test-confirm') |
|
476 |
self.run_script(""" |
|
477 |
$ bzr test-confirm |
|
478 |
2>Really do it? [y/n]: |
|
479 |
<yes |
|
480 |
yes |
|
481 |
""") |
|
4665.5.20
by Vincent Ladeuil
Fixed as per Martin's review. |
482 |
|
5509.1.1
by Neil Martinsen-Burrell
add ignore_blanks to run_script to recover old behavior |
483 |
To avoid having to specify "-q" for all commands whose output is |
484 |
irrelevant, the run_script() method may be passed the keyword argument |
|
5531.1.2
by Vincent Ladeuil
s/blank_output/null_output/ |
485 |
``null_output_matches_anything=True``. For example:: |
5509.1.1
by Neil Martinsen-Burrell
add ignore_blanks to run_script to recover old behavior |
486 |
|
5531.1.2
by Vincent Ladeuil
s/blank_output/null_output/ |
487 |
def test_ignoring_null_output(self): |
5509.1.1
by Neil Martinsen-Burrell
add ignore_blanks to run_script to recover old behavior |
488 |
self.run_script(""" |
489 |
$ bzr init |
|
490 |
$ bzr ci -m 'first revision' --unchanged |
|
491 |
$ bzr log --line |
|
492 |
1: ... |
|
5531.1.2
by Vincent Ladeuil
s/blank_output/null_output/ |
493 |
""", null_output_matches_anything=True) |
5509.1.1
by Neil Martinsen-Burrell
add ignore_blanks to run_script to recover old behavior |
494 |
|
495 |
||
5017.2.2
by Martin Pool
Add import tariff tests |
496 |
Import tariff tests |
497 |
------------------- |
|
498 |
||
499 |
`bzrlib.tests.test_import_tariff` has some tests that measure how many |
|
500 |
Python modules are loaded to run some representative commands. |
|
501 |
||
502 |
We want to avoid loading code unnecessarily, for reasons including: |
|
503 |
||
504 |
* Python modules are interpreted when they're loaded, either to define |
|
505 |
classes or modules or perhaps to initialize some structures. |
|
506 |
||
507 |
* With a cold cache we may incur blocking real disk IO for each module. |
|
508 |
||
509 |
* Some modules depend on many others. |
|
510 |
||
511 |
* Some optional modules such as `testtools` are meant to be soft |
|
512 |
dependencies and only needed for particular cases. If they're loaded in |
|
513 |
other cases then bzr may break for people who don't have those modules. |
|
514 |
||
5279.1.1
by Andrew Bennetts
lazy_import most things in merge.py; add a few representative modules to the import tariff tests; tweak a couple of other modules so that patiencediff is not necessarily imported; remove a bunch of unused imports from test_knit.py. |
515 |
`test_import_tariff` allows us to check that removal of imports doesn't |
5017.2.2
by Martin Pool
Add import tariff tests |
516 |
regress. |
517 |
||
518 |
This is done by running the command in a subprocess with |
|
5938.1.1
by Vincent Ladeuil
Better explain why tariff tests need to escape the test isolation jail. |
519 |
``PYTHON_VERBOSE=1``. Starting a whole Python interpreter is pretty slow, |
520 |
so we don't want exhaustive testing here, but just enough to guard against |
|
521 |
distinct fixed problems. |
|
5017.2.2
by Martin Pool
Add import tariff tests |
522 |
|
523 |
Assertions about precisely what is loaded tend to be brittle so we instead |
|
524 |
make assertions that particular things aren't loaded. |
|
525 |
||
526 |
Unless selftest is run with ``--no-plugins``, modules will be loaded in |
|
527 |
the usual way and checks made on what they cause to be loaded. This is |
|
528 |
probably worth checking into, because many bzr users have at least some |
|
529 |
plugins installed (and they're included in binary installers). |
|
530 |
||
531 |
In theory, plugins might have a good reason to load almost anything: |
|
532 |
someone might write a plugin that opens a network connection or pops up a |
|
533 |
gui window every time you run 'bzr status'. However, it's more likely |
|
534 |
that the code to do these things is just being loaded accidentally. We |
|
535 |
might eventually need to have a way to make exceptions for particular |
|
536 |
plugins. |
|
537 |
||
538 |
Some things to check: |
|
539 |
||
540 |
* non-GUI commands shouldn't load GUI libraries |
|
541 |
||
542 |
* operations on bzr native formats sholudn't load foreign branch libraries |
|
543 |
||
544 |
* network code shouldn't be loaded for purely local operations |
|
545 |
||
546 |
* particularly expensive Python built-in modules shouldn't be loaded |
|
547 |
unless there is a good reason |
|
3619.3.1
by Andrew Bennetts
Move the notes on writing tests out of HACKING into a new file, and improve |
548 |
|
549 |
||
4634.146.7
by Danny van Heumen
Updated documentation on how to approach testing locking behaviour. |
550 |
Testing locking behaviour |
551 |
------------------------- |
|
552 |
||
553 |
In order to test the locking behaviour of commands, it is possible to install |
|
554 |
a hook that is called when a write lock is: acquired, released or broken. |
|
555 |
(Read locks also exist, they cannot be discovered in this way.) |
|
556 |
||
557 |
A hook can be installed by calling bzrlib.lock.Lock.hooks.install_named_hook. |
|
558 |
The three valid hooks are: `lock_acquired`, `lock_released` and `lock_broken`. |
|
559 |
||
560 |
Example:: |
|
561 |
||
562 |
locks_acquired = [] |
|
563 |
locks_released = [] |
|
564 |
||
565 |
lock.Lock.hooks.install_named_hook('lock_acquired', |
|
566 |
locks_acquired.append, None) |
|
567 |
lock.Lock.hooks.install_named_hook('lock_released', |
|
568 |
locks_released.append, None) |
|
569 |
||
570 |
`locks_acquired` will now receive a LockResult instance for all locks acquired |
|
571 |
since the time the hook is installed. |
|
572 |
||
4634.146.10
by Danny van Heumen
Updated documentation: added case for BzrDir (removed "special case" remark) and removed explanation for LockResult representation. |
573 |
The last part of the `lock_url` allows you to identify the type of object that is locked. |
574 |
||
575 |
- BzrDir: `/branch-lock` |
|
576 |
- Working tree: `/checkout/lock` |
|
577 |
- Branch: `/branch/lock` |
|
578 |
- Repository: `/repository/lock` |
|
4634.146.7
by Danny van Heumen
Updated documentation on how to approach testing locking behaviour. |
579 |
|
580 |
To test if a lock is a write lock on a working tree, one can do the following:: |
|
581 |
||
582 |
self.assertEndsWith(locks_acquired[0].lock_url, "/checkout/lock") |
|
583 |
||
584 |
See bzrlib/tests/commands/test_revert.py for an example of how to use this for |
|
585 |
testing locks. |
|
586 |
||
5077.3.1
by Martin Pool
Tip on testing locking behaviour |
587 |
|
3619.3.1
by Andrew Bennetts
Move the notes on writing tests out of HACKING into a new file, and improve |
588 |
Skipping tests |
589 |
-------------- |
|
590 |
||
591 |
In our enhancements to unittest we allow for some addition results beyond |
|
592 |
just success or failure. |
|
593 |
||
594 |
If a test can't be run, it can say that it's skipped by raising a special |
|
5193.5.8
by Vincent Ladeuil
Revert previous change as I can't reproduce the related problem anymore. |
595 |
exception. This is typically used in parameterized tests |--| for example |
3619.3.1
by Andrew Bennetts
Move the notes on writing tests out of HACKING into a new file, and improve |
596 |
if a transport doesn't support setting permissions, we'll skip the tests |
597 |
that relating to that. :: |
|
598 |
||
599 |
try: |
|
600 |
return self.branch_format.initialize(repo.bzrdir) |
|
601 |
except errors.UninitializableFormat: |
|
602 |
raise tests.TestSkipped('Uninitializable branch format') |
|
603 |
||
604 |
Raising TestSkipped is a good idea when you want to make it clear that the |
|
605 |
test was not run, rather than just returning which makes it look as if it |
|
606 |
was run and passed. |
|
607 |
||
608 |
Several different cases are distinguished: |
|
609 |
||
610 |
TestSkipped |
|
611 |
Generic skip; the only type that was present up to bzr 0.18. |
|
612 |
||
613 |
TestNotApplicable |
|
614 |
The test doesn't apply to the parameters with which it was run. |
|
615 |
This is typically used when the test is being applied to all |
|
616 |
implementations of an interface, but some aspects of the interface |
|
617 |
are optional and not present in particular concrete |
|
618 |
implementations. (Some tests that should raise this currently |
|
619 |
either silently return or raise TestSkipped.) Another option is |
|
620 |
to use more precise parameterization to avoid generating the test |
|
621 |
at all. |
|
622 |
||
623 |
UnavailableFeature |
|
624 |
The test can't be run because a dependency (typically a Python |
|
625 |
library) is not available in the test environment. These |
|
626 |
are in general things that the person running the test could fix |
|
627 |
by installing the library. It's OK if some of these occur when |
|
628 |
an end user runs the tests or if we're specifically testing in a |
|
629 |
limited environment, but a full test should never see them. |
|
630 |
||
631 |
See `Test feature dependencies`_ below. |
|
632 |
||
633 |
KnownFailure |
|
634 |
The test exists but is known to fail, for example this might be |
|
635 |
appropriate to raise if you've committed a test for a bug but not |
|
636 |
the fix for it, or if something works on Unix but not on Windows. |
|
4853.1.1
by Patrick Regan
Removed trailing whitespace from files in doc directory |
637 |
|
3619.3.1
by Andrew Bennetts
Move the notes on writing tests out of HACKING into a new file, and improve |
638 |
Raising this allows you to distinguish these failures from the |
639 |
ones that are not expected to fail. If the test would fail |
|
640 |
because of something we don't expect or intend to fix, |
|
641 |
KnownFailure is not appropriate, and TestNotApplicable might be |
|
642 |
better. |
|
643 |
||
644 |
KnownFailure should be used with care as we don't want a |
|
645 |
proliferation of quietly broken tests. |
|
646 |
||
4873.2.4
by John Arbash Meinel
Add a NEWS entry and an entry in the testing docs about ModuleAvailableFeature |
647 |
|
648 |
||
3619.3.1
by Andrew Bennetts
Move the notes on writing tests out of HACKING into a new file, and improve |
649 |
We plan to support three modes for running the test suite to control the |
650 |
interpretation of these results. Strict mode is for use in situations |
|
651 |
like merges to the mainline and releases where we want to make sure that |
|
652 |
everything that can be tested has been tested. Lax mode is for use by |
|
653 |
developers who want to temporarily tolerate some known failures. The |
|
654 |
default behaviour is obtained by ``bzr selftest`` with no options, and |
|
655 |
also (if possible) by running under another unittest harness. |
|
656 |
||
657 |
======================= ======= ======= ======== |
|
658 |
result strict default lax |
|
659 |
======================= ======= ======= ======== |
|
660 |
TestSkipped pass pass pass |
|
661 |
TestNotApplicable pass pass pass |
|
3619.3.2
by Andrew Bennetts
Remove references to unimplemented TestPlatformLimit, remove some redundant (and misplaced) text from 'Test feature dependencies'. |
662 |
UnavailableFeature fail pass pass |
3619.3.1
by Andrew Bennetts
Move the notes on writing tests out of HACKING into a new file, and improve |
663 |
KnownFailure fail pass pass |
664 |
======================= ======= ======= ======== |
|
4853.1.1
by Patrick Regan
Removed trailing whitespace from files in doc directory |
665 |
|
3619.3.1
by Andrew Bennetts
Move the notes on writing tests out of HACKING into a new file, and improve |
666 |
|
667 |
Test feature dependencies |
|
668 |
------------------------- |
|
669 |
||
670 |
Writing tests that require a feature |
|
671 |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|
672 |
||
673 |
Rather than manually checking the environment in each test, a test class |
|
674 |
can declare its dependence on some test features. The feature objects are |
|
675 |
checked only once for each run of the whole test suite. |
|
676 |
||
677 |
(For historical reasons, as of May 2007 many cases that should depend on |
|
678 |
features currently raise TestSkipped.) |
|
679 |
||
680 |
For example:: |
|
681 |
||
682 |
class TestStrace(TestCaseWithTransport): |
|
683 |
||
684 |
_test_needs_features = [StraceFeature] |
|
685 |
||
3619.3.2
by Andrew Bennetts
Remove references to unimplemented TestPlatformLimit, remove some redundant (and misplaced) text from 'Test feature dependencies'. |
686 |
This means all tests in this class need the feature. If the feature is |
687 |
not available the test will be skipped using UnavailableFeature. |
|
3619.3.1
by Andrew Bennetts
Move the notes on writing tests out of HACKING into a new file, and improve |
688 |
|
689 |
Individual tests can also require a feature using the ``requireFeature`` |
|
690 |
method:: |
|
691 |
||
692 |
self.requireFeature(StraceFeature) |
|
693 |
||
5004.2.1
by Martin Pool
Better documentation of ModuleAvailableFeature |
694 |
The old naming style for features is CamelCase, but because they're |
695 |
actually instances not classses they're now given instance-style names |
|
696 |
like ``apport``. |
|
697 |
||
698 |
Features already defined in ``bzrlib.tests`` and ``bzrlib.tests.features`` |
|
699 |
include: |
|
700 |
||
701 |
- apport |
|
702 |
- paramiko |
|
703 |
- SymlinkFeature |
|
704 |
- HardlinkFeature |
|
705 |
- OsFifoFeature |
|
706 |
- UnicodeFilenameFeature |
|
707 |
- FTPServerFeature |
|
3619.3.1
by Andrew Bennetts
Move the notes on writing tests out of HACKING into a new file, and improve |
708 |
- CaseInsensitiveFilesystemFeature. |
5094.3.1
by Martin Pool
``.bazaar``, ``.bazaar/bazaar.conf`` and ``.bzr.log`` inherit user and group ownership from the containing directory. This allow bzr to work better with sudo. |
709 |
- chown_feature: The test can rely on OS being POSIX and python |
5051.4.6
by Parth Malwankar
documented ChownFeature in testing.txt |
710 |
supporting os.chown. |
5094.3.1
by Martin Pool
``.bazaar``, ``.bazaar/bazaar.conf`` and ``.bzr.log`` inherit user and group ownership from the containing directory. This allow bzr to work better with sudo. |
711 |
- posix_permissions_feature: The test can use POSIX-style |
712 |
user/group/other permission bits. |
|
3619.3.1
by Andrew Bennetts
Move the notes on writing tests out of HACKING into a new file, and improve |
713 |
|
714 |
||
715 |
Defining a new feature that tests can require |
|
716 |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|
717 |
||
718 |
New features for use with ``_test_needs_features`` or ``requireFeature`` |
|
719 |
are defined by subclassing ``bzrlib.tests.Feature`` and overriding the |
|
720 |
``_probe`` and ``feature_name`` methods. For example:: |
|
721 |
||
722 |
class _SymlinkFeature(Feature): |
|
4853.1.1
by Patrick Regan
Removed trailing whitespace from files in doc directory |
723 |
|
3619.3.1
by Andrew Bennetts
Move the notes on writing tests out of HACKING into a new file, and improve |
724 |
def _probe(self): |
725 |
return osutils.has_symlinks() |
|
4853.1.1
by Patrick Regan
Removed trailing whitespace from files in doc directory |
726 |
|
3619.3.1
by Andrew Bennetts
Move the notes on writing tests out of HACKING into a new file, and improve |
727 |
def feature_name(self): |
728 |
return 'symlinks' |
|
4853.1.1
by Patrick Regan
Removed trailing whitespace from files in doc directory |
729 |
|
3619.3.1
by Andrew Bennetts
Move the notes on writing tests out of HACKING into a new file, and improve |
730 |
SymlinkFeature = _SymlinkFeature() |
731 |
||
5004.2.1
by Martin Pool
Better documentation of ModuleAvailableFeature |
732 |
A helper for handling running tests based on whether a python |
733 |
module is available. This can handle 3rd-party dependencies (is |
|
734 |
``paramiko`` available?) as well as stdlib (``termios``) or |
|
735 |
extension modules (``bzrlib._groupcompress_pyx``). You create a |
|
736 |
new feature instance with:: |
|
737 |
||
738 |
# in bzrlib/tests/features.py |
|
739 |
apport = tests.ModuleAvailableFeature('apport') |
|
740 |
||
741 |
||
742 |
# then in bzrlib/tests/test_apport.py |
|
743 |
class TestApportReporting(TestCaseInTempDir): |
|
744 |
||
745 |
_test_needs_features = [features.apport] |
|
746 |
||
3619.3.1
by Andrew Bennetts
Move the notes on writing tests out of HACKING into a new file, and improve |
747 |
|
5432.6.1
by John C Barstow
Mention applyDeprecated in doc/developers/testing.txt |
748 |
Testing deprecated code |
749 |
----------------------- |
|
750 |
||
751 |
When code is deprecated, it is still supported for some length of time, |
|
752 |
usually until the next major version. The ``applyDeprecated`` helper |
|
753 |
wraps calls to deprecated code to verify that it is correctly issuing the |
|
754 |
deprecation warning, and also prevents the warnings from being printed |
|
755 |
during test runs. |
|
756 |
||
757 |
Typically patches that apply the ``@deprecated_function`` decorator should |
|
758 |
update the accompanying tests to use the ``applyDeprecated`` wrapper. |
|
759 |
||
760 |
``applyDeprecated`` is defined in ``bzrlib.tests.TestCase``. See the API |
|
761 |
docs for more details. |
|
762 |
||
763 |
||
3619.3.1
by Andrew Bennetts
Move the notes on writing tests out of HACKING into a new file, and improve |
764 |
Testing exceptions and errors |
765 |
----------------------------- |
|
766 |
||
767 |
It's important to test handling of errors and exceptions. Because this |
|
768 |
code is often not hit in ad-hoc testing it can often have hidden bugs -- |
|
769 |
it's particularly common to get NameError because the exception code |
|
770 |
references a variable that has since been renamed. |
|
771 |
||
772 |
.. TODO: Something about how to provoke errors in the right way? |
|
773 |
||
774 |
In general we want to test errors at two levels: |
|
775 |
||
776 |
1. A test in ``test_errors.py`` checking that when the exception object is |
|
777 |
constructed with known parameters it produces an expected string form. |
|
778 |
This guards against mistakes in writing the format string, or in the |
|
779 |
``str`` representations of its parameters. There should be one for |
|
780 |
each exception class. |
|
781 |
||
782 |
2. Tests that when an api is called in a particular situation, it raises |
|
783 |
an error of the expected class. You should typically use |
|
784 |
``assertRaises``, which in the Bazaar test suite returns the exception |
|
785 |
object to allow you to examine its parameters. |
|
786 |
||
787 |
In some cases blackbox tests will also want to check error reporting. But |
|
788 |
it can be difficult to provoke every error through the commandline |
|
5193.5.8
by Vincent Ladeuil
Revert previous change as I can't reproduce the related problem anymore. |
789 |
interface, so those tests are only done as needed |--| eg in response to a |
3619.3.1
by Andrew Bennetts
Move the notes on writing tests out of HACKING into a new file, and improve |
790 |
particular bug or if the error is reported in an unusual way(?) Blackbox |
791 |
tests should mostly be testing how the command-line interface works, so |
|
792 |
should only test errors if there is something particular to the cli in how |
|
793 |
they're displayed or handled. |
|
794 |
||
795 |
||
796 |
Testing warnings |
|
797 |
---------------- |
|
798 |
||
799 |
The Python ``warnings`` module is used to indicate a non-fatal code |
|
800 |
problem. Code that's expected to raise a warning can be tested through |
|
801 |
callCatchWarnings. |
|
802 |
||
803 |
The test suite can be run with ``-Werror`` to check no unexpected errors |
|
804 |
occur. |
|
805 |
||
806 |
However, warnings should be used with discretion. It's not an appropriate |
|
807 |
way to give messages to the user, because the warning is normally shown |
|
808 |
only once per source line that causes the problem. You should also think |
|
809 |
about whether the warning is serious enought that it should be visible to |
|
810 |
users who may not be able to fix it. |
|
811 |
||
812 |
||
813 |
Interface implementation testing and test scenarios |
|
814 |
--------------------------------------------------- |
|
815 |
||
816 |
There are several cases in Bazaar of multiple implementations of a common |
|
817 |
conceptual interface. ("Conceptual" because it's not necessary for all |
|
818 |
the implementations to share a base class, though they often do.) |
|
819 |
Examples include transports and the working tree, branch and repository |
|
820 |
classes. |
|
821 |
||
822 |
In these cases we want to make sure that every implementation correctly |
|
823 |
fulfils the interface requirements. For example, every Transport should |
|
824 |
support the ``has()`` and ``get()`` and ``clone()`` methods. We have a |
|
825 |
sub-suite of tests in ``test_transport_implementations``. (Most |
|
826 |
per-implementation tests are in submodules of ``bzrlib.tests``, but not |
|
827 |
the transport tests at the moment.) |
|
828 |
||
829 |
These tests are repeated for each registered Transport, by generating a |
|
830 |
new TestCase instance for the cross product of test methods and transport |
|
831 |
implementations. As each test runs, it has ``transport_class`` and |
|
832 |
``transport_server`` set to the class it should test. Most tests don't |
|
833 |
access these directly, but rather use ``self.get_transport`` which returns |
|
834 |
a transport of the appropriate type. |
|
835 |
||
836 |
The goal is to run per-implementation only the tests that relate to that |
|
837 |
particular interface. Sometimes we discover a bug elsewhere that happens |
|
838 |
with only one particular transport. Once it's isolated, we can consider |
|
839 |
whether a test should be added for that particular implementation, |
|
840 |
or for all implementations of the interface. |
|
841 |
||
842 |
See also `Per-implementation tests`_ (above). |
|
843 |
||
844 |
||
5462.3.12
by Martin Pool
Doc for variations |
845 |
Test scenarios and variations |
846 |
----------------------------- |
|
3619.3.1
by Andrew Bennetts
Move the notes on writing tests out of HACKING into a new file, and improve |
847 |
|
848 |
Some utilities are provided for generating variations of tests. This can |
|
849 |
be used for per-implementation tests, or other cases where the same test |
|
850 |
code needs to run several times on different scenarios. |
|
851 |
||
852 |
The general approach is to define a class that provides test methods, |
|
853 |
which depend on attributes of the test object being pre-set with the |
|
854 |
values to which the test should be applied. The test suite should then |
|
855 |
also provide a list of scenarios in which to run the tests. |
|
856 |
||
5462.3.14
by Martin Pool
Unify varations with scenario protocol |
857 |
A single *scenario* is defined by a `(name, parameter_dict)` tuple. The |
858 |
short string name is combined with the name of the test method to form the |
|
859 |
test instance name. The parameter dict is merged into the instance's |
|
860 |
attributes. |
|
3619.3.1
by Andrew Bennetts
Move the notes on writing tests out of HACKING into a new file, and improve |
861 |
|
5462.3.17
by Martin Pool
Updated test scenario docs |
862 |
For example:: |
863 |
||
5462.3.21
by Martin Pool
Rename to load_tests_apply_scenarios |
864 |
load_tests = load_tests_apply_scenarios |
5462.3.17
by Martin Pool
Updated test scenario docs |
865 |
|
866 |
class TestCheckout(TestCase): |
|
867 |
||
5559.2.1
by Martin Pool
Format and name correction for test scenario docs |
868 |
scenarios = multiply_scenarios( |
869 |
VaryByRepositoryFormat(), |
|
870 |
VaryByTreeFormat(), |
|
871 |
) |
|
5462.3.14
by Martin Pool
Unify varations with scenario protocol |
872 |
|
873 |
The `load_tests` declaration or definition should be near the top of the |
|
874 |
file so its effect can be seen. |
|
875 |
||
3619.3.1
by Andrew Bennetts
Move the notes on writing tests out of HACKING into a new file, and improve |
876 |
|
877 |
Test support |
|
878 |
------------ |
|
879 |
||
880 |
We have a rich collection of tools to support writing tests. Please use |
|
881 |
them in preference to ad-hoc solutions as they provide portability and |
|
882 |
performance benefits. |
|
883 |
||
884 |
||
885 |
TestCase and its subclasses |
|
886 |
~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|
887 |
||
888 |
The ``bzrlib.tests`` module defines many TestCase classes to help you |
|
889 |
write your tests. |
|
890 |
||
891 |
TestCase |
|
892 |
A base TestCase that extends the Python standard library's |
|
5200.3.3
by Robert Collins
Lock methods on ``Tree``, ``Branch`` and ``Repository`` are now |
893 |
TestCase in several ways. TestCase is build on |
894 |
``testtools.TestCase``, which gives it support for more assertion |
|
895 |
methods (e.g. ``assertContainsRe``), ``addCleanup``, and other |
|
896 |
features (see its API docs for details). It also has a ``setUp`` that |
|
897 |
makes sure that global state like registered hooks and loggers won't |
|
898 |
interfere with your test. All tests should use this base class |
|
899 |
(whether directly or via a subclass). Note that we are trying not to |
|
900 |
add more assertions at this point, and instead to build up a library |
|
901 |
of ``bzrlib.tests.matchers``. |
|
3619.3.1
by Andrew Bennetts
Move the notes on writing tests out of HACKING into a new file, and improve |
902 |
|
903 |
TestCaseWithMemoryTransport |
|
904 |
Extends TestCase and adds methods like ``get_transport``, |
|
905 |
``make_branch`` and ``make_branch_builder``. The files created are |
|
906 |
stored in a MemoryTransport that is discarded at the end of the test. |
|
907 |
This class is good for tests that need to make branches or use |
|
908 |
transports, but that don't require storing things on disk. All tests |
|
909 |
that create bzrdirs should use this base class (either directly or via |
|
910 |
a subclass) as it ensures that the test won't accidentally operate on |
|
911 |
real branches in your filesystem. |
|
912 |
||
913 |
TestCaseInTempDir |
|
914 |
Extends TestCaseWithMemoryTransport. For tests that really do need |
|
915 |
files to be stored on disk, e.g. because a subprocess uses a file, or |
|
916 |
for testing functionality that accesses the filesystem directly rather |
|
917 |
than via the Transport layer (such as dirstate). |
|
918 |
||
919 |
TestCaseWithTransport |
|
920 |
Extends TestCaseInTempDir. Provides ``get_url`` and |
|
921 |
``get_readonly_url`` facilities. Subclasses can control the |
|
922 |
transports used by setting ``vfs_transport_factory``, |
|
923 |
``transport_server`` and/or ``transport_readonly_server``. |
|
924 |
||
925 |
||
926 |
See the API docs for more details. |
|
927 |
||
928 |
||
929 |
BranchBuilder |
|
930 |
~~~~~~~~~~~~~ |
|
931 |
||
932 |
When writing a test for a feature, it is often necessary to set up a |
|
933 |
branch with a certain history. The ``BranchBuilder`` interface allows the |
|
934 |
creation of test branches in a quick and easy manner. Here's a sample |
|
935 |
session:: |
|
936 |
||
937 |
builder = self.make_branch_builder('relpath') |
|
938 |
builder.build_commit() |
|
939 |
builder.build_commit() |
|
940 |
builder.build_commit() |
|
941 |
branch = builder.get_branch() |
|
942 |
||
943 |
``make_branch_builder`` is a method of ``TestCaseWithMemoryTransport``. |
|
944 |
||
945 |
Note that many current tests create test branches by inheriting from |
|
946 |
``TestCaseWithTransport`` and using the ``make_branch_and_tree`` helper to |
|
947 |
give them a ``WorkingTree`` that they can commit to. However, using the |
|
948 |
newer ``make_branch_builder`` helper is preferred, because it can build |
|
949 |
the changes in memory, rather than on disk. Tests that are explictly |
|
950 |
testing how we work with disk objects should, of course, use a real |
|
951 |
``WorkingTree``. |
|
952 |
||
953 |
Please see bzrlib.branchbuilder for more details. |
|
954 |
||
4070.5.2
by Martin Pool
Recommend setting timestamp in BranchBuilder |
955 |
If you're going to examine the commit timestamps e.g. in a test for log |
956 |
output, you should set the timestamp on the tree, rather than using fuzzy |
|
957 |
matches in the test. |
|
958 |
||
3619.3.1
by Andrew Bennetts
Move the notes on writing tests out of HACKING into a new file, and improve |
959 |
|
960 |
TreeBuilder |
|
961 |
~~~~~~~~~~~ |
|
962 |
||
963 |
The ``TreeBuilder`` interface allows the construction of arbitrary trees |
|
964 |
with a declarative interface. A sample session might look like:: |
|
965 |
||
966 |
tree = self.make_branch_and_tree('path') |
|
967 |
builder = TreeBuilder() |
|
968 |
builder.start_tree(tree) |
|
969 |
builder.build(['foo', "bar/", "bar/file"]) |
|
970 |
tree.commit('commit the tree') |
|
971 |
builder.finish_tree() |
|
972 |
||
973 |
Usually a test will create a tree using ``make_branch_and_memory_tree`` (a |
|
974 |
method of ``TestCaseWithMemoryTransport``) or ``make_branch_and_tree`` (a |
|
975 |
method of ``TestCaseWithTransport``). |
|
976 |
||
977 |
Please see bzrlib.treebuilder for more details. |
|
978 |
||
5616.8.1
by Aaron Bentley
Add documentation of PreviewTree in testing. |
979 |
PreviewTree |
980 |
~~~~~~~~~~~ |
|
981 |
||
982 |
PreviewTrees are based on TreeTransforms. This means they can represent |
|
983 |
virtually any state that a WorkingTree can have, including unversioned files. |
|
984 |
They can be used to test the output of anything that produces TreeTransforms, |
|
985 |
such as merge algorithms and revert. They can also be used to test anything |
|
986 |
that takes arbitrary Trees as its input. |
|
987 |
||
5616.8.2
by Andrew Bennetts
Fix ReST formatting. |
988 |
:: |
989 |
||
5616.8.1
by Aaron Bentley
Add documentation of PreviewTree in testing. |
990 |
# Get an empty tree to base the transform on. |
991 |
b = self.make_branch('.') |
|
992 |
empty_tree = b.repository.revision_tree(_mod_revision.NULL_REVISION) |
|
993 |
tt = TransformPreview(empty_tree) |
|
994 |
self.addCleanup(tt.finalize) |
|
995 |
# Empty trees don't have a root, so add it first. |
|
996 |
root = tt.new_directory('', ROOT_PARENT, 'tree-root') |
|
997 |
# Set the contents of a file. |
|
998 |
tt.new_file('new-file', root, 'contents', 'file-id') |
|
999 |
preview = tt.get_preview_tree() |
|
1000 |
# Test the contents. |
|
1001 |
self.assertEqual('contents', preview.get_file_text('file-id')) |
|
1002 |
||
5616.8.2
by Andrew Bennetts
Fix ReST formatting. |
1003 |
PreviewTrees can stack, with each tree falling back to the previous:: |
5616.8.1
by Aaron Bentley
Add documentation of PreviewTree in testing. |
1004 |
|
1005 |
tt2 = TransformPreview(preview) |
|
1006 |
self.addCleanup(tt2.finalize) |
|
1007 |
tt2.new_file('new-file2', tt2.root, 'contents2', 'file-id2') |
|
1008 |
preview2 = tt2.get_preview_tree() |
|
1009 |
self.assertEqual('contents', preview2.get_file_text('file-id')) |
|
1010 |
self.assertEqual('contents2', preview2.get_file_text('file-id2')) |
|
1011 |
||
5193.5.8
by Vincent Ladeuil
Revert previous change as I can't reproduce the related problem anymore. |
1012 |
|
4986.2.7
by Martin Pool
Recommend overrideAttr in the test writing guide |
1013 |
Temporarily changing state |
1014 |
~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|
1015 |
||
1016 |
If your test needs to temporarily mutate some global state, and you need |
|
1017 |
it restored at the end, you can say for example:: |
|
1018 |
||
1019 |
self.overrideAttr(osutils, '_cached_user_encoding', 'latin-1') |
|
1020 |
||
6006.4.1
by Martin Pool
Add recordCalls test helper |
1021 |
This should be used with discretion; sometimes it's better to make the |
1022 |
underlying code more testable so that you don't need to rely on monkey |
|
1023 |
patching. |
|
1024 |
||
1025 |
||
1026 |
Observing calls to a function |
|
1027 |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|
1028 |
||
1029 |
Sometimes it's useful to observe how a function is called, typically when |
|
1030 |
calling it has side effects but the side effects are not easy to observe |
|
1031 |
from a test case. For instance the function may be expensive and we want |
|
1032 |
to assert it is not called too many times, or it has effects on the |
|
1033 |
machine that are safe to run during a test but not easy to measure. In |
|
1034 |
these cases, you can use `recordCalls` which will monkey-patch in a |
|
1035 |
wrapper that records when the function is called. |
|
1036 |
||
1037 |
||
5570.3.17
by Vincent Ladeuil
Final tweaks and doc. |
1038 |
Temporarily changing environment variables |
1039 |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|
1040 |
||
1041 |
If yout test needs to temporarily change some environment variable value |
|
1042 |
(which generally means you want it restored at the end), you can use:: |
|
1043 |
||
1044 |
self.overrideEnv('BZR_ENV_VAR', 'new_value') |
|
1045 |
||
1046 |
If you want to remove a variable from the environment, you should use the |
|
1047 |
special ``None`` value:: |
|
1048 |
||
1049 |
self.overrideEnv('PATH', None) |
|
1050 |
||
1051 |
If you add a new feature which depends on a new environment variable, make |
|
1052 |
sure it behaves properly when this variable is not defined (if applicable) and |
|
1053 |
if you need to enforce a specific default value, check the |
|
1054 |
``TestCase._cleanEnvironment`` in ``bzrlib.tests.__init__.py`` which defines a |
|
1055 |
proper set of values for all tests. |
|
1056 |
||
4986.2.7
by Martin Pool
Recommend overrideAttr in the test writing guide |
1057 |
Cleaning up |
4986.2.2
by Martin Pool
Doc about using addCleanup not tearDown |
1058 |
~~~~~~~~~~~ |
1059 |
||
1060 |
Our base ``TestCase`` class provides an ``addCleanup`` method, which |
|
1061 |
should be used instead of ``tearDown``. All the cleanups are run when the |
|
1062 |
test finishes, regardless of whether it passes or fails. If one cleanup |
|
1063 |
fails, later cleanups are still run. |
|
1064 |
||
1065 |
(The same facility is available outside of tests through |
|
1066 |
``bzrlib.cleanup``.) |
|
1067 |
||
5335.3.5
by Martin Pool
merge trunk |
1068 |
|
5335.3.3
by Martin Pool
Developer documentation about tc qdisc |
1069 |
Manual testing |
1070 |
============== |
|
1071 |
||
1072 |
Generally we prefer automated testing but sometimes a manual test is the |
|
1073 |
right thing, especially for performance tests that want to measure elapsed |
|
1074 |
time rather than effort. |
|
1075 |
||
1076 |
Simulating slow networks |
|
1077 |
------------------------ |
|
1078 |
||
1079 |
To get realistically slow network performance for manually measuring |
|
1080 |
performance, we can simulate 500ms latency (thus 1000ms round trips):: |
|
1081 |
||
1082 |
$ sudo tc qdisc add dev lo root netem delay 500ms |
|
1083 |
||
1084 |
Normal system behaviour is restored with :: |
|
1085 |
||
1086 |
$ sudo tc qdisc del dev lo root |
|
1087 |
||
1088 |
A more precise version that only filters traffic to port 4155 is:: |
|
1089 |
||
1090 |
tc qdisc add dev lo root handle 1: prio |
|
1091 |
tc qdisc add dev lo parent 1:3 handle 30: netem delay 500ms |
|
6050.2.1
by Martin Pool
Updated docs for tc qdisc, since the kernel interface seems to have changed (thanks abentley) |
1092 |
tc filter add dev lo protocol ip parent 1:0 prio 3 u32 match ip dport 4155 0xffff flowid 1:3 |
1093 |
tc filter add dev lo protocol ip parent 1:0 prio 3 u32 match ip sport 4155 0xffff flowid 1:3 |
|
5335.3.3
by Martin Pool
Developer documentation about tc qdisc |
1094 |
|
1095 |
and to remove this:: |
|
1096 |
||
1097 |
tc filter del dev lo protocol ip parent 1: pref 3 u32 |
|
1098 |
tc qdisc del dev lo root handle 1: |
|
1099 |
||
5335.3.4
by Martin Pool
Review tweaks to testing documentation |
1100 |
You can use similar code to add additional delay to a real network |
1101 |
interface, perhaps only when talking to a particular server or pointing at |
|
1102 |
a VM. For more information see <http://lartc.org/>. |
|
1103 |
||
5335.3.3
by Martin Pool
Developer documentation about tc qdisc |
1104 |
|
5193.5.8
by Vincent Ladeuil
Revert previous change as I can't reproduce the related problem anymore. |
1105 |
.. |--| unicode:: U+2014 |
1106 |
||
3619.3.1
by Andrew Bennetts
Move the notes on writing tests out of HACKING into a new file, and improve |
1107 |
.. |
5283.1.1
by Martin Pool
Add helper function script.run_script and suggest using it |
1108 |
vim: ft=rst tw=74 ai et sw=4 |