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. |
Guido van Rossum | f58ed25 | 1997-03-07 21:04:33 +0000 | [diff] [blame] | 19 | |
| 20 | If -v is given *twice*, the tests themselves are run in verbose mode. |
| 21 | This is incompatible with -g and does not compare test output files. |
Guido van Rossum | 152494a | 1996-12-20 03:12:20 +0000 | [diff] [blame] | 22 | """ |
| 23 | |
| 24 | import sys |
| 25 | import string |
| 26 | import os |
| 27 | import getopt |
Guido van Rossum | 9e48b27 | 1997-07-16 01:56:13 +0000 | [diff] [blame] | 28 | import traceback |
Guido van Rossum | 152494a | 1996-12-20 03:12:20 +0000 | [diff] [blame] | 29 | |
| 30 | import test_support |
| 31 | |
| 32 | def main(): |
| 33 | try: |
| 34 | opts, args = getopt.getopt(sys.argv[1:], 'vgqx') |
| 35 | except getopt.error, msg: |
| 36 | print msg |
| 37 | print __doc__ |
Guido van Rossum | e838701 | 1997-08-14 19:40:34 +0000 | [diff] [blame] | 38 | return 2 |
Guido van Rossum | 152494a | 1996-12-20 03:12:20 +0000 | [diff] [blame] | 39 | verbose = 0 |
| 40 | quiet = 0 |
| 41 | generate = 0 |
| 42 | exclude = 0 |
| 43 | for o, a in opts: |
Guido van Rossum | f58ed25 | 1997-03-07 21:04:33 +0000 | [diff] [blame] | 44 | if o == '-v': verbose = verbose+1 |
Guido van Rossum | 152494a | 1996-12-20 03:12:20 +0000 | [diff] [blame] | 45 | if o == '-q': quiet = 1 |
| 46 | if o == '-g': generate = 1 |
| 47 | if o == '-x': exclude = 1 |
Guido van Rossum | f58ed25 | 1997-03-07 21:04:33 +0000 | [diff] [blame] | 48 | if generate and verbose>1: |
| 49 | print "-g and more than one -v don't go together!" |
Guido van Rossum | e838701 | 1997-08-14 19:40:34 +0000 | [diff] [blame] | 50 | return 2 |
Guido van Rossum | 152494a | 1996-12-20 03:12:20 +0000 | [diff] [blame] | 51 | good = [] |
| 52 | bad = [] |
| 53 | skipped = [] |
| 54 | if exclude: |
| 55 | nottests[:0] = args |
| 56 | args = [] |
| 57 | tests = args or findtests() |
Guido van Rossum | f58ed25 | 1997-03-07 21:04:33 +0000 | [diff] [blame] | 58 | test_support.verbose = verbose>1 # Tell tests to be moderately quiet |
Guido van Rossum | 152494a | 1996-12-20 03:12:20 +0000 | [diff] [blame] | 59 | for test in tests: |
| 60 | if verbose: |
| 61 | print test |
Guido van Rossum | f58ed25 | 1997-03-07 21:04:33 +0000 | [diff] [blame] | 62 | ok = runtest(test, generate, verbose>1) |
Guido van Rossum | 152494a | 1996-12-20 03:12:20 +0000 | [diff] [blame] | 63 | if ok > 0: |
| 64 | good.append(test) |
| 65 | elif ok == 0: |
| 66 | bad.append(test) |
| 67 | else: |
| 68 | if not quiet: |
| 69 | print "test", test, |
| 70 | print "skipped -- an optional feature could not be imported" |
| 71 | skipped.append(test) |
| 72 | if good and not quiet: |
| 73 | if not bad and not skipped and len(good) > 1: |
| 74 | print "All", |
| 75 | print count(len(good), "test"), "OK." |
| 76 | if bad: |
| 77 | print count(len(bad), "test"), "failed:", |
| 78 | print string.join(bad) |
| 79 | if skipped and not quiet: |
| 80 | print count(len(skipped), "test"), "skipped:", |
| 81 | print string.join(skipped) |
Guido van Rossum | e838701 | 1997-08-14 19:40:34 +0000 | [diff] [blame] | 82 | return len(bad) > 0 |
Guido van Rossum | 152494a | 1996-12-20 03:12:20 +0000 | [diff] [blame] | 83 | |
| 84 | stdtests = [ |
| 85 | 'test_grammar', |
| 86 | 'test_opcodes', |
| 87 | 'test_operations', |
| 88 | 'test_builtin', |
| 89 | 'test_exceptions', |
| 90 | 'test_types', |
| 91 | ] |
| 92 | |
| 93 | nottests = [ |
| 94 | 'test_support', |
| 95 | 'test_b1', |
| 96 | 'test_b2', |
| 97 | ] |
| 98 | |
| 99 | def findtests(): |
| 100 | """Return a list of all applicable test modules.""" |
| 101 | testdir = findtestdir() |
| 102 | names = os.listdir(testdir) |
| 103 | tests = [] |
| 104 | for name in names: |
| 105 | if name[:5] == "test_" and name[-3:] == ".py": |
| 106 | modname = name[:-3] |
| 107 | if modname not in stdtests and modname not in nottests: |
| 108 | tests.append(modname) |
| 109 | tests.sort() |
| 110 | return stdtests + tests |
| 111 | |
Guido van Rossum | f58ed25 | 1997-03-07 21:04:33 +0000 | [diff] [blame] | 112 | def runtest(test, generate, verbose2): |
Guido van Rossum | 152494a | 1996-12-20 03:12:20 +0000 | [diff] [blame] | 113 | test_support.unload(test) |
| 114 | testdir = findtestdir() |
| 115 | outputdir = os.path.join(testdir, "output") |
| 116 | outputfile = os.path.join(outputdir, test) |
| 117 | try: |
| 118 | if generate: |
| 119 | cfp = open(outputfile, "w") |
Guido van Rossum | f58ed25 | 1997-03-07 21:04:33 +0000 | [diff] [blame] | 120 | elif verbose2: |
| 121 | cfp = sys.stdout |
Guido van Rossum | 152494a | 1996-12-20 03:12:20 +0000 | [diff] [blame] | 122 | else: |
| 123 | cfp = Compare(outputfile) |
| 124 | except IOError: |
| 125 | cfp = None |
| 126 | print "Warning: can't open", outputfile |
| 127 | try: |
| 128 | save_stdout = sys.stdout |
| 129 | try: |
| 130 | if cfp: |
| 131 | sys.stdout = cfp |
| 132 | print test # Output file starts with test name |
| 133 | __import__(test) |
| 134 | finally: |
| 135 | sys.stdout = save_stdout |
| 136 | except ImportError, msg: |
| 137 | return -1 |
| 138 | except test_support.TestFailed, msg: |
| 139 | print "test", test, "failed --", msg |
| 140 | return 0 |
Guido van Rossum | 9e48b27 | 1997-07-16 01:56:13 +0000 | [diff] [blame] | 141 | except: |
| 142 | print "test", test, "crashed --", sys.exc_type, ":", sys.exc_value |
| 143 | if verbose2: |
| 144 | traceback.print_exc(file=sys.stdout) |
| 145 | return 0 |
Guido van Rossum | 152494a | 1996-12-20 03:12:20 +0000 | [diff] [blame] | 146 | else: |
| 147 | return 1 |
| 148 | |
| 149 | def findtestdir(): |
| 150 | if __name__ == '__main__': |
| 151 | file = sys.argv[0] |
| 152 | else: |
| 153 | file = __file__ |
| 154 | testdir = os.path.dirname(file) or os.curdir |
| 155 | return testdir |
| 156 | |
| 157 | def count(n, word): |
| 158 | if n == 1: |
| 159 | return "%d %s" % (n, word) |
| 160 | else: |
| 161 | return "%d %ss" % (n, word) |
| 162 | |
| 163 | class Compare: |
| 164 | |
| 165 | def __init__(self, filename): |
| 166 | self.fp = open(filename, 'r') |
| 167 | |
| 168 | def write(self, data): |
| 169 | expected = self.fp.read(len(data)) |
| 170 | if data <> expected: |
| 171 | raise test_support.TestFailed, \ |
| 172 | 'Writing: '+`data`+', expected: '+`expected` |
| 173 | |
Guido van Rossum | 75fce30 | 1997-07-17 14:51:37 +0000 | [diff] [blame] | 174 | def flush(self): |
| 175 | pass |
| 176 | |
Guido van Rossum | 152494a | 1996-12-20 03:12:20 +0000 | [diff] [blame] | 177 | def close(self): |
| 178 | leftover = self.fp.read() |
| 179 | if leftover: |
| 180 | raise test_support.TestFailed, 'Unread: '+`leftover` |
| 181 | self.fp.close() |
| 182 | |
| 183 | def isatty(self): |
| 184 | return 0 |
| 185 | |
| 186 | if __name__ == '__main__': |
Guido van Rossum | e838701 | 1997-08-14 19:40:34 +0000 | [diff] [blame] | 187 | sys.exit(main()) |