Guido van Rossum | 152494a | 1996-12-20 03:12:20 +0000 | [diff] [blame] | 1 | #! /usr/bin/env python |
| 2 | |
| 3 | """Regression test. |
| 4 | |
| 5 | This will find all modules whose name is "test_*" in the test |
| 6 | directory, and run them. Various command line options provide |
| 7 | additional facilities. |
| 8 | |
| 9 | Command line options: |
| 10 | |
| 11 | -v: verbose -- print the name name of each test as it is being run |
| 12 | -q: quiet -- don't print anything except if a test fails |
| 13 | -g: generate -- write the output file for a test instead of comparing it |
| 14 | -x: exclude -- arguments are tests to *exclude* |
| 15 | |
| 16 | If non-option arguments are present, they are names for tests to run, |
| 17 | unless -x is given, in which case they are names for tests not to run. |
| 18 | If no test names are given, all tests are run. |
| 19 | """ |
| 20 | |
| 21 | import sys |
| 22 | import string |
| 23 | import os |
| 24 | import getopt |
| 25 | |
| 26 | import test_support |
| 27 | |
| 28 | def main(): |
| 29 | try: |
| 30 | opts, args = getopt.getopt(sys.argv[1:], 'vgqx') |
| 31 | except getopt.error, msg: |
| 32 | print msg |
| 33 | print __doc__ |
| 34 | sys.exit(2) |
| 35 | verbose = 0 |
| 36 | quiet = 0 |
| 37 | generate = 0 |
| 38 | exclude = 0 |
| 39 | for o, a in opts: |
| 40 | if o == '-v': verbose = 1 |
| 41 | if o == '-q': quiet = 1 |
| 42 | if o == '-g': generate = 1 |
| 43 | if o == '-x': exclude = 1 |
| 44 | good = [] |
| 45 | bad = [] |
| 46 | skipped = [] |
| 47 | if exclude: |
| 48 | nottests[:0] = args |
| 49 | args = [] |
| 50 | tests = args or findtests() |
| 51 | test_support.verbose = 0 # Tell tests to be moderately quiet |
| 52 | for test in tests: |
| 53 | if verbose: |
| 54 | print test |
| 55 | ok = runtest(test, generate) |
| 56 | if ok > 0: |
| 57 | good.append(test) |
| 58 | elif ok == 0: |
| 59 | bad.append(test) |
| 60 | else: |
| 61 | if not quiet: |
| 62 | print "test", test, |
| 63 | print "skipped -- an optional feature could not be imported" |
| 64 | skipped.append(test) |
| 65 | if good and not quiet: |
| 66 | if not bad and not skipped and len(good) > 1: |
| 67 | print "All", |
| 68 | print count(len(good), "test"), "OK." |
| 69 | if bad: |
| 70 | print count(len(bad), "test"), "failed:", |
| 71 | print string.join(bad) |
| 72 | if skipped and not quiet: |
| 73 | print count(len(skipped), "test"), "skipped:", |
| 74 | print string.join(skipped) |
| 75 | sys.exit(len(bad) > 0) |
| 76 | |
| 77 | stdtests = [ |
| 78 | 'test_grammar', |
| 79 | 'test_opcodes', |
| 80 | 'test_operations', |
| 81 | 'test_builtin', |
| 82 | 'test_exceptions', |
| 83 | 'test_types', |
| 84 | ] |
| 85 | |
| 86 | nottests = [ |
| 87 | 'test_support', |
| 88 | 'test_b1', |
| 89 | 'test_b2', |
| 90 | ] |
| 91 | |
| 92 | def findtests(): |
| 93 | """Return a list of all applicable test modules.""" |
| 94 | testdir = findtestdir() |
| 95 | names = os.listdir(testdir) |
| 96 | tests = [] |
| 97 | for name in names: |
| 98 | if name[:5] == "test_" and name[-3:] == ".py": |
| 99 | modname = name[:-3] |
| 100 | if modname not in stdtests and modname not in nottests: |
| 101 | tests.append(modname) |
| 102 | tests.sort() |
| 103 | return stdtests + tests |
| 104 | |
| 105 | def runtest(test, generate): |
| 106 | test_support.unload(test) |
| 107 | testdir = findtestdir() |
| 108 | outputdir = os.path.join(testdir, "output") |
| 109 | outputfile = os.path.join(outputdir, test) |
| 110 | try: |
| 111 | if generate: |
| 112 | cfp = open(outputfile, "w") |
| 113 | else: |
| 114 | cfp = Compare(outputfile) |
| 115 | except IOError: |
| 116 | cfp = None |
| 117 | print "Warning: can't open", outputfile |
| 118 | try: |
| 119 | save_stdout = sys.stdout |
| 120 | try: |
| 121 | if cfp: |
| 122 | sys.stdout = cfp |
| 123 | print test # Output file starts with test name |
| 124 | __import__(test) |
| 125 | finally: |
| 126 | sys.stdout = save_stdout |
| 127 | except ImportError, msg: |
| 128 | return -1 |
| 129 | except test_support.TestFailed, msg: |
| 130 | print "test", test, "failed --", msg |
| 131 | return 0 |
| 132 | else: |
| 133 | return 1 |
| 134 | |
| 135 | def findtestdir(): |
| 136 | if __name__ == '__main__': |
| 137 | file = sys.argv[0] |
| 138 | else: |
| 139 | file = __file__ |
| 140 | testdir = os.path.dirname(file) or os.curdir |
| 141 | return testdir |
| 142 | |
| 143 | def count(n, word): |
| 144 | if n == 1: |
| 145 | return "%d %s" % (n, word) |
| 146 | else: |
| 147 | return "%d %ss" % (n, word) |
| 148 | |
| 149 | class Compare: |
| 150 | |
| 151 | def __init__(self, filename): |
| 152 | self.fp = open(filename, 'r') |
| 153 | |
| 154 | def write(self, data): |
| 155 | expected = self.fp.read(len(data)) |
| 156 | if data <> expected: |
| 157 | raise test_support.TestFailed, \ |
| 158 | 'Writing: '+`data`+', expected: '+`expected` |
| 159 | |
| 160 | def close(self): |
| 161 | leftover = self.fp.read() |
| 162 | if leftover: |
| 163 | raise test_support.TestFailed, 'Unread: '+`leftover` |
| 164 | self.fp.close() |
| 165 | |
| 166 | def isatty(self): |
| 167 | return 0 |
| 168 | |
| 169 | if __name__ == '__main__': |
| 170 | main() |