Guido van Rossum | 85f1820 | 1992-11-27 22:53:50 +0000 | [diff] [blame] | 1 | # Automatic Python regression test. |
| 2 | # |
| 3 | # Some essential parts of the Python interpreter are tested by the module |
| 4 | # 'testall'. (Despite its name, it doesn't test everything -- that would |
| 5 | # be a truly Herculean task!) When a test fails, 'testall' raises an |
| 6 | # exception. When all tests succeed, it produces quite a lot of output. |
| 7 | # |
| 8 | # For a normal regression test, this output is never looked at unless |
| 9 | # something goes wrong. Thus, it would be wise to suppress the output |
| 10 | # normally. This module does that, but it doesn't just throw the output |
| 11 | # from 'testall' away -- it compares it with the output from a previous |
| 12 | # run. If a difference is noticed it raises an exception; if all is well, |
| 13 | # it prints nothing except 'All tests OK.' at the very end. |
| 14 | # |
| 15 | # The output from a previous run is supposed to be in a file 'testall.out' |
| 16 | # somewhere on the search path for modules (sys.path, initialized from |
| 17 | # $PYTHONPATH plus some default places). |
| 18 | # |
| 19 | # Of course, if the normal output of the tests is changed because the |
| 20 | # tests have been changed (rather than a test producing the wrong output), |
| 21 | # 'autotest' will fail as well. In this case, run 'testall' manually |
| 22 | # and direct its output to 'testall.out'. |
| 23 | # |
| 24 | # The comparison uses (and demonstrates!) a rather new Python feature: |
| 25 | # program output that normally goes to stdout (by 'print' statements |
| 26 | # or by writing directly to sys.stdout) can be redirected to an |
| 27 | # arbitrary class instance as long as it has a 'write' method. |
| 28 | |
| 29 | import os |
| 30 | import sys |
| 31 | |
| 32 | # Function to find a file somewhere on sys.path |
| 33 | def findfile(filename): |
| 34 | for dirname in sys.path: |
| 35 | fullname = os.path.join(dirname, filename) |
| 36 | if os.path.exists(fullname): |
| 37 | return fullname |
| 38 | return filename # Will cause exception later |
| 39 | |
| 40 | # Exception raised when the test failed (not the same as in test_support) |
| 41 | TestFailed = 'autotest.TestFailed' |
| 42 | |
| 43 | # Class substituted for sys.stdout, to compare it with the given file |
| 44 | class Compare: |
| 45 | def init(self, filename): |
| 46 | self.fp = open(filename, 'r') |
| 47 | return self |
| 48 | def write(self, data): |
| 49 | expected = self.fp.read(len(data)) |
| 50 | if data <> expected: |
| 51 | raise TestFailed, \ |
| 52 | 'Writing: '+`data`+', expected: '+`expected` |
| 53 | def close(self): |
| 54 | self.fp.close() |
| 55 | |
| 56 | # The main program |
| 57 | def main(): |
| 58 | import sys |
| 59 | filename = findfile('testall.out') |
| 60 | real_stdout = sys.stdout |
| 61 | try: |
| 62 | sys.stdout = Compare().init(filename) |
| 63 | import testall |
| 64 | finally: |
| 65 | sys.stdout = real_stdout |
| 66 | print 'All tests OK.' |
| 67 | |
| 68 | main() |