Skip Montanaro | e9e5dcd | 2000-07-19 17:19:49 +0000 | [diff] [blame] | 1 | Writing Python Regression Tests |
| 2 | ------------------------------- |
Skip Montanaro | 47c60ec | 2000-06-30 06:08:35 +0000 | [diff] [blame] | 3 | Skip Montanaro |
Skip Montanaro | e9e5dcd | 2000-07-19 17:19:49 +0000 | [diff] [blame] | 4 | (skip@mojam.com) |
| 5 | |
| 6 | |
| 7 | Introduction |
Skip Montanaro | 47c60ec | 2000-06-30 06:08:35 +0000 | [diff] [blame] | 8 | |
| 9 | If you add a new module to Python or modify the functionality of an existing |
Skip Montanaro | e9e5dcd | 2000-07-19 17:19:49 +0000 | [diff] [blame] | 10 | module, you should write one or more test cases to exercise that new |
| 11 | functionality. The mechanics of how the test system operates are fairly |
| 12 | straightforward. When a test case is run, the output is compared with the |
| 13 | expected output that is stored in .../Lib/test/output. If the test runs to |
| 14 | completion and the actual and expected outputs match, the test succeeds, if |
| 15 | not, it fails. If an ImportError is raised, the test is not run. |
Skip Montanaro | 47c60ec | 2000-06-30 06:08:35 +0000 | [diff] [blame] | 16 | |
Skip Montanaro | e9e5dcd | 2000-07-19 17:19:49 +0000 | [diff] [blame] | 17 | You will be writing unit tests (isolated tests of functions and objects |
| 18 | defined by the module) using white box techniques. Unlike black box |
| 19 | testing, where you only have the external interfaces to guide your test case |
| 20 | writing, in white box testing you can see the code being tested and tailor |
| 21 | your test cases to exercise it more completely. In particular, you will be |
| 22 | able to refer to the C and Python code in the CVS repository when writing |
| 23 | your regression test cases. |
Skip Montanaro | 47c60ec | 2000-06-30 06:08:35 +0000 | [diff] [blame] | 24 | |
Skip Montanaro | e9e5dcd | 2000-07-19 17:19:49 +0000 | [diff] [blame] | 25 | |
| 26 | Executing Test Cases |
| 27 | |
| 28 | If you are writing test cases for module spam, you need to create a file |
| 29 | in .../Lib/test named test_spam.py and an expected output file in |
| 30 | .../Lib/test/output named test_spam ("..." represents the top-level |
| 31 | directory in the Python source tree, the directory containing the configure |
| 32 | script). From the top-level directory, generate the initial version of the |
| 33 | test output file by executing: |
| 34 | |
| 35 | ./python Lib/test/regrtest.py -g test_spam.py |
| 36 | |
| 37 | Any time you modify test_spam.py you need to generate a new expected |
Skip Montanaro | 47c60ec | 2000-06-30 06:08:35 +0000 | [diff] [blame] | 38 | output file. Don't forget to desk check the generated output to make sure |
| 39 | it's really what you expected to find! To run a single test after modifying |
| 40 | a module, simply run regrtest.py without the -g flag: |
| 41 | |
Skip Montanaro | e9e5dcd | 2000-07-19 17:19:49 +0000 | [diff] [blame] | 42 | ./python Lib/test/regrtest.py test_spam.py |
| 43 | |
| 44 | While debugging a regression test, you can of course execute it |
| 45 | independently of the regression testing framework and see what it prints: |
| 46 | |
| 47 | ./python Lib/test/test_spam.py |
Skip Montanaro | 47c60ec | 2000-06-30 06:08:35 +0000 | [diff] [blame] | 48 | |
| 49 | To run the entire test suite, make the "test" target at the top level: |
| 50 | |
Skip Montanaro | 47c60ec | 2000-06-30 06:08:35 +0000 | [diff] [blame] | 51 | make test |
| 52 | |
Skip Montanaro | e9e5dcd | 2000-07-19 17:19:49 +0000 | [diff] [blame] | 53 | On non-Unix platforms where make may not be available, you can simply |
| 54 | execute the two runs of regrtest (optimized and non-optimized) directly: |
| 55 | |
| 56 | ./python Lib/test/regrtest.py |
| 57 | ./python -O Lib/test/regrtest.py |
| 58 | |
| 59 | |
| 60 | Test cases generate output based upon values computed by the test code. |
| 61 | When executed, regrtest.py compares the actual output generated by executing |
| 62 | the test case with the expected output and reports success or failure. It |
| 63 | stands to reason that if the actual and expected outputs are to match, they |
| 64 | must not contain any machine dependencies. This means your test cases |
| 65 | should not print out absolute machine addresses (e.g. the return value of |
| 66 | the id() builtin function) or floating point numbers with large numbers of |
| 67 | significant digits (unless you understand what you are doing!). |
| 68 | |
| 69 | |
| 70 | Test Case Writing Tips |
Skip Montanaro | 47c60ec | 2000-06-30 06:08:35 +0000 | [diff] [blame] | 71 | |
| 72 | Writing good test cases is a skilled task and is too complex to discuss in |
| 73 | detail in this short document. Many books have been written on the subject. |
| 74 | I'll show my age by suggesting that Glenford Myers' "The Art of Software |
| 75 | Testing", published in 1979, is still the best introduction to the subject |
| 76 | available. It is short (177 pages), easy to read, and discusses the major |
| 77 | elements of software testing, though its publication predates the |
| 78 | object-oriented software revolution, so doesn't cover that subject at all. |
| 79 | Unfortunately, it is very expensive (about $100 new). If you can borrow it |
| 80 | or find it used (around $20), I strongly urge you to pick up a copy. |
| 81 | |
Skip Montanaro | 47c60ec | 2000-06-30 06:08:35 +0000 | [diff] [blame] | 82 | The most important goal when writing test cases is to break things. A test |
Skip Montanaro | e9e5dcd | 2000-07-19 17:19:49 +0000 | [diff] [blame] | 83 | case that doesn't uncover a bug is much less valuable than one that does. |
| 84 | In designing test cases you should pay attention to the following: |
Skip Montanaro | 47c60ec | 2000-06-30 06:08:35 +0000 | [diff] [blame] | 85 | |
Skip Montanaro | e9e5dcd | 2000-07-19 17:19:49 +0000 | [diff] [blame] | 86 | * Your test cases should exercise all the functions and objects defined |
| 87 | in the module, not just the ones meant to be called by users of your |
| 88 | module. This may require you to write test code that uses the module |
| 89 | in ways you don't expect (explicitly calling internal functions, for |
| 90 | example - see test_atexit.py). |
Skip Montanaro | 47c60ec | 2000-06-30 06:08:35 +0000 | [diff] [blame] | 91 | |
Skip Montanaro | e9e5dcd | 2000-07-19 17:19:49 +0000 | [diff] [blame] | 92 | * You should consider any boundary values that may tickle exceptional |
| 93 | conditions (e.g. if you were writing regression tests for division, |
| 94 | you might well want to generate tests with numerators and denominators |
| 95 | at the limits of floating point and integer numbers on the machine |
| 96 | performing the tests as well as a denominator of zero). |
Skip Montanaro | 47c60ec | 2000-06-30 06:08:35 +0000 | [diff] [blame] | 97 | |
Skip Montanaro | e9e5dcd | 2000-07-19 17:19:49 +0000 | [diff] [blame] | 98 | * You should exercise as many paths through the code as possible. This |
| 99 | may not always be possible, but is a goal to strive for. In |
| 100 | particular, when considering if statements (or their equivalent), you |
| 101 | want to create test cases that exercise both the true and false |
| 102 | branches. For loops, you should create test cases that exercise the |
| 103 | loop zero, one and multiple times. |
| 104 | |
| 105 | * You should test with obviously invalid input. If you know that a |
| 106 | function requires an integer input, try calling it with other types of |
| 107 | objects to see how it responds. |
| 108 | |
| 109 | * You should test with obviously out-of-range input. If the domain of a |
| 110 | function is only defined for positive integers, try calling it with a |
| 111 | negative integer. |
| 112 | |
| 113 | * If you are going to fix a bug that wasn't uncovered by an existing |
| 114 | test, try to write a test case that exposes the bug (preferably before |
| 115 | fixing it). |
| 116 | |
| 117 | |
| 118 | Regression Test Writing Rules |
| 119 | |
| 120 | Each test case is different. There is no "standard" form for a Python |
| 121 | regression test case, though there are some general rules: |
| 122 | |
| 123 | * If your test case detects a failure, raise TestFailed (found in |
| 124 | test_support). |
| 125 | |
| 126 | * Import everything you'll need as early as possible. |
| 127 | |
| 128 | * If you'll be importing objects from a module that is at least |
| 129 | partially platform-dependent, only import those objects you need for |
| 130 | the current test case to avoid spurious ImportError exceptions that |
| 131 | prevent the test from running to completion. |
| 132 | |
| 133 | * Print all your test case results using the print statement. For |
| 134 | non-fatal errors, print an error message (or omit a successful |
| 135 | completion print) to indicate the failure, but proceed instead of |
| 136 | raising TestFailed. |
| 137 | |
| 138 | |
| 139 | Miscellaneous |
| 140 | |
| 141 | There is a test_support module you can import from your test case. It |
| 142 | provides the following useful objects: |
| 143 | |
| 144 | * TestFailed - raise this exception when your regression test detects a |
| 145 | failure. |
| 146 | |
| 147 | * findfile(file) - you can call this function to locate a file somewhere |
| 148 | along sys.path or in the Lib/test tree - see test_linuxaudiodev.py for |
| 149 | an example of its use. |
| 150 | |
| 151 | * verbose - you can use this variable to control print output. Many |
| 152 | modules use it. Search for "verbose" in the test_*.py files to see |
| 153 | lots of examples. |
| 154 | |
| 155 | * fcmp(x,y) - you can call this function to compare two floating point |
| 156 | numbers when you expect them to only be approximately equal withing a |
| 157 | fuzz factor (test_support.FUZZ, which defaults to 1e-6). |
| 158 | |
| 159 | Python and C statement coverage results are currently available at |
| 160 | |
| 161 | http://www.musi-cal.com/~skip/python/Python/dist/src/ |
| 162 | |
| 163 | As of this writing (July, 2000) these results are being generated nightly. |
| 164 | You can refer to the summaries and the test coverage output files to see |
| 165 | where coverage is adequate or lacking and write test cases to beef up the |
| 166 | coverage. |