Skip Montanaro | 47c60ec | 2000-06-30 06:08:35 +0000 | [diff] [blame] | 1 | Writing Python Test Cases |
| 2 | ------------------------- |
| 3 | Skip Montanaro |
| 4 | |
| 5 | If you add a new module to Python or modify the functionality of an existing |
| 6 | module, it is your responsibility to write one or more test cases to test |
| 7 | that new functionality. The mechanics of the test system are fairly |
| 8 | straightforward. If you are writing test cases for module zyzzyx, you need |
| 9 | to create a file in .../Lib/test named test_zyzzyx.py and an expected output |
| 10 | file in .../Lib/test/output named test_zyzzyx ("..." represents the |
| 11 | top-level directory in the Python source tree, the directory containing the |
| 12 | configure script). Generate the initial version of the test output file by |
| 13 | executing: |
| 14 | |
| 15 | cd .../Lib/test |
| 16 | python regrtest.py -g test_zyzzyx.py |
| 17 | |
| 18 | Any time you modify test_zyzzyx.py you need to generate a new expected |
| 19 | output file. Don't forget to desk check the generated output to make sure |
| 20 | it's really what you expected to find! To run a single test after modifying |
| 21 | a module, simply run regrtest.py without the -g flag: |
| 22 | |
| 23 | cd .../Lib/test |
| 24 | python regrtest.py test_zyzzyx.py |
| 25 | |
| 26 | To run the entire test suite, make the "test" target at the top level: |
| 27 | |
| 28 | cd ... |
| 29 | make test |
| 30 | |
| 31 | Test cases generate output based upon computed values and branches taken in |
| 32 | the code. When executed, regrtest.py compares the actual output generated |
| 33 | by executing the test case with the expected output and reports success or |
| 34 | failure. It stands to reason that if the actual and expected outputs are to |
| 35 | match, they must not contain any machine dependencies. This means |
| 36 | your test cases should not print out absolute machine addresses or floating |
| 37 | point numbers with large numbers of significant digits. |
| 38 | |
| 39 | Writing good test cases is a skilled task and is too complex to discuss in |
| 40 | detail in this short document. Many books have been written on the subject. |
| 41 | I'll show my age by suggesting that Glenford Myers' "The Art of Software |
| 42 | Testing", published in 1979, is still the best introduction to the subject |
| 43 | available. It is short (177 pages), easy to read, and discusses the major |
| 44 | elements of software testing, though its publication predates the |
| 45 | object-oriented software revolution, so doesn't cover that subject at all. |
| 46 | Unfortunately, it is very expensive (about $100 new). If you can borrow it |
| 47 | or find it used (around $20), I strongly urge you to pick up a copy. |
| 48 | |
| 49 | As an author of at least part of a module, you will be writing unit tests |
| 50 | (isolated tests of functions and objects defined by the module) using white |
| 51 | box techniques. (Unlike black box testing, where you only have the external |
| 52 | interfaces to guide your test case writing, in white box testing you can see |
| 53 | the code being tested and tailor your test cases to exercise it more |
| 54 | completely). |
| 55 | |
| 56 | The most important goal when writing test cases is to break things. A test |
| 57 | case that doesn't uncover a bug is less valuable than one that does. In |
| 58 | designing test cases you should pay attention to the following: |
| 59 | |
| 60 | 1. Your test cases should exercise all the functions and objects defined |
| 61 | in the module, not just the ones meant to be called by users of your |
| 62 | module. This may require you to write test code that uses the module |
| 63 | in ways you don't expect (explicitly calling internal functions, for |
| 64 | example - see test_atexit.py). |
| 65 | |
| 66 | 2. You should consider any boundary values that may tickle exceptional |
| 67 | conditions (e.g. if you were testing a division module you might well |
| 68 | want to generate tests with numerators and denominators at the limits |
| 69 | of floating point and integer numbers on the machine performing the |
| 70 | tests as well as a denominator of zero). |
| 71 | |
| 72 | 3. You should exercise as many paths through the code as possible. This |
| 73 | may not always be possible, but is a goal to strive for. In |
| 74 | particular, when considering if statements (or their equivalent), you |
| 75 | want to create test cases that exercise both the true and false |
| 76 | branches. For while and for statements, you should create test cases |
| 77 | that exercise the loop zero, one and multiple times. |