blob: 5944f8f364879419f794a90d36276f71e4400f48 [file] [log] [blame]
Guido van Rossum152494a1996-12-20 03:12:20 +00001#! /usr/bin/env python
2
3"""Regression test.
4
5This will find all modules whose name is "test_*" in the test
6directory, and run them. Various command line options provide
7additional facilities.
8
9Command line options:
10
Guido van Rossuma4122201997-08-18 20:08:24 +000011-v: verbose -- run tests in verbose mode with output to stdout
Guido van Rossum152494a1996-12-20 03:12:20 +000012-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
16If non-option arguments are present, they are names for tests to run,
17unless -x is given, in which case they are names for tests not to run.
18If no test names are given, all tests are run.
Guido van Rossumf58ed251997-03-07 21:04:33 +000019
Guido van Rossuma4122201997-08-18 20:08:24 +000020-v is incompatible with -g and does not compare test output files.
Guido van Rossum152494a1996-12-20 03:12:20 +000021"""
22
23import sys
24import string
25import os
26import getopt
Guido van Rossum9e48b271997-07-16 01:56:13 +000027import traceback
Guido van Rossum152494a1996-12-20 03:12:20 +000028
29import test_support
30
Guido van Rossum6fd83b71998-08-01 17:04:08 +000031def main(tests=None, testdir=None):
32 """Execute a test suite.
33
34 This also parses command-line options and modifies its behaviour
35 accordingly.
36
37 tests -- a list of strings containing test names (optional)
38 testdir -- the directory in which to look for tests (optional)
39
40 Users other than the Python test suite will certainly want to
41 specify testdir; if it's omitted, the directory containing the
42 Python test suite is searched for.
43
44 If the tests argument is omitted, the tests listed on the
45 command-line will be used. If that's empty, too, then all *.py
46 files beginning with test_ will be used.
47
48 """
49
Guido van Rossum152494a1996-12-20 03:12:20 +000050 try:
Guido van Rossum41360a41998-03-26 19:42:58 +000051 opts, args = getopt.getopt(sys.argv[1:], 'vgqx')
Guido van Rossum152494a1996-12-20 03:12:20 +000052 except getopt.error, msg:
Guido van Rossum41360a41998-03-26 19:42:58 +000053 print msg
54 print __doc__
55 return 2
Guido van Rossum152494a1996-12-20 03:12:20 +000056 verbose = 0
57 quiet = 0
58 generate = 0
59 exclude = 0
60 for o, a in opts:
Guido van Rossum41360a41998-03-26 19:42:58 +000061 if o == '-v': verbose = verbose+1
62 if o == '-q': quiet = 1; verbose = 0
63 if o == '-g': generate = 1
64 if o == '-x': exclude = 1
Guido van Rossuma4122201997-08-18 20:08:24 +000065 if generate and verbose:
Guido van Rossum41360a41998-03-26 19:42:58 +000066 print "-g and -v don't go together!"
67 return 2
Guido van Rossum152494a1996-12-20 03:12:20 +000068 good = []
69 bad = []
70 skipped = []
Guido van Rossuma4122201997-08-18 20:08:24 +000071 for i in range(len(args)):
Guido van Rossum41360a41998-03-26 19:42:58 +000072 # Strip trailing ".py" from arguments
73 if args[i][-3:] == '.py':
74 args[i] = args[i][:-3]
Guido van Rossum6c74fea1998-08-25 12:29:08 +000075 stdtests = STDTESTS[:]
76 nottests = NOTTESTS[:]
Guido van Rossum152494a1996-12-20 03:12:20 +000077 if exclude:
Guido van Rossum6c74fea1998-08-25 12:29:08 +000078 for arg in args:
79 if arg in stdtests:
80 stdtests.remove(arg)
81 nottests[:0] = args
Guido van Rossum41360a41998-03-26 19:42:58 +000082 args = []
Guido van Rossum747e1ca1998-08-24 13:48:36 +000083 tests = tests or args or findtests(testdir, stdtests, nottests)
Guido van Rossum41360a41998-03-26 19:42:58 +000084 test_support.verbose = verbose # Tell tests to be moderately quiet
Guido van Rossum152494a1996-12-20 03:12:20 +000085 for test in tests:
Guido van Rossum41360a41998-03-26 19:42:58 +000086 if not quiet:
87 print test
Guido van Rossum6fd83b71998-08-01 17:04:08 +000088 ok = runtest(test, generate, verbose, testdir)
Guido van Rossum41360a41998-03-26 19:42:58 +000089 if ok > 0:
90 good.append(test)
91 elif ok == 0:
92 bad.append(test)
93 else:
94 if not quiet:
95 print "test", test,
96 print "skipped -- an optional feature could not be imported"
97 skipped.append(test)
Guido van Rossum152494a1996-12-20 03:12:20 +000098 if good and not quiet:
Guido van Rossum41360a41998-03-26 19:42:58 +000099 if not bad and not skipped and len(good) > 1:
100 print "All",
101 print count(len(good), "test"), "OK."
Guido van Rossum152494a1996-12-20 03:12:20 +0000102 if bad:
Guido van Rossum41360a41998-03-26 19:42:58 +0000103 print count(len(bad), "test"), "failed:",
104 print string.join(bad)
Guido van Rossum152494a1996-12-20 03:12:20 +0000105 if skipped and not quiet:
Guido van Rossum41360a41998-03-26 19:42:58 +0000106 print count(len(skipped), "test"), "skipped:",
107 print string.join(skipped)
Guido van Rossume8387011997-08-14 19:40:34 +0000108 return len(bad) > 0
Guido van Rossum152494a1996-12-20 03:12:20 +0000109
Guido van Rossum6fd83b71998-08-01 17:04:08 +0000110STDTESTS = [
Guido van Rossum152494a1996-12-20 03:12:20 +0000111 'test_grammar',
112 'test_opcodes',
113 'test_operations',
114 'test_builtin',
115 'test_exceptions',
116 'test_types',
117 ]
118
Guido van Rossum6fd83b71998-08-01 17:04:08 +0000119NOTTESTS = [
Guido van Rossum152494a1996-12-20 03:12:20 +0000120 'test_support',
121 'test_b1',
122 'test_b2',
123 ]
124
Guido van Rossum6fd83b71998-08-01 17:04:08 +0000125def findtests(testdir=None, stdtests=STDTESTS, nottests=NOTTESTS):
Guido van Rossum152494a1996-12-20 03:12:20 +0000126 """Return a list of all applicable test modules."""
Guido van Rossum6fd83b71998-08-01 17:04:08 +0000127 if not testdir: testdir = findtestdir()
Guido van Rossum152494a1996-12-20 03:12:20 +0000128 names = os.listdir(testdir)
129 tests = []
130 for name in names:
Guido van Rossum41360a41998-03-26 19:42:58 +0000131 if name[:5] == "test_" and name[-3:] == ".py":
132 modname = name[:-3]
133 if modname not in stdtests and modname not in nottests:
134 tests.append(modname)
Guido van Rossum152494a1996-12-20 03:12:20 +0000135 tests.sort()
136 return stdtests + tests
137
Guido van Rossum6fd83b71998-08-01 17:04:08 +0000138def runtest(test, generate, verbose, testdir = None):
139 """Run a single test.
140 test -- the name of the test
141 generate -- if true, generate output, instead of running the test
142 and comparing it to a previously created output file
143 verbose -- if true, print more messages
144 testdir -- test directory
145 """
Guido van Rossum152494a1996-12-20 03:12:20 +0000146 test_support.unload(test)
Guido van Rossum6fd83b71998-08-01 17:04:08 +0000147 if not testdir: testdir = findtestdir()
Guido van Rossum152494a1996-12-20 03:12:20 +0000148 outputdir = os.path.join(testdir, "output")
149 outputfile = os.path.join(outputdir, test)
150 try:
Guido van Rossum41360a41998-03-26 19:42:58 +0000151 if generate:
152 cfp = open(outputfile, "w")
153 elif verbose:
154 cfp = sys.stdout
155 else:
156 cfp = Compare(outputfile)
Guido van Rossum152494a1996-12-20 03:12:20 +0000157 except IOError:
Guido van Rossum41360a41998-03-26 19:42:58 +0000158 cfp = None
159 print "Warning: can't open", outputfile
Guido van Rossum152494a1996-12-20 03:12:20 +0000160 try:
Guido van Rossum41360a41998-03-26 19:42:58 +0000161 save_stdout = sys.stdout
162 try:
163 if cfp:
164 sys.stdout = cfp
165 print test # Output file starts with test name
166 __import__(test, globals(), locals(), [])
167 finally:
168 sys.stdout = save_stdout
Guido van Rossum152494a1996-12-20 03:12:20 +0000169 except ImportError, msg:
Guido van Rossum41360a41998-03-26 19:42:58 +0000170 return -1
Guido van Rossum4e8ef5f1997-10-20 23:46:54 +0000171 except KeyboardInterrupt, v:
Guido van Rossum41360a41998-03-26 19:42:58 +0000172 raise KeyboardInterrupt, v, sys.exc_info()[2]
Guido van Rossum152494a1996-12-20 03:12:20 +0000173 except test_support.TestFailed, msg:
Guido van Rossum41360a41998-03-26 19:42:58 +0000174 print "test", test, "failed --", msg
175 return 0
Guido van Rossum9e48b271997-07-16 01:56:13 +0000176 except:
Guido van Rossum41360a41998-03-26 19:42:58 +0000177 type, value = sys.exc_info()[:2]
178 print "test", test, "crashed --", type, ":", value
179 if verbose:
180 traceback.print_exc(file=sys.stdout)
181 return 0
Guido van Rossum152494a1996-12-20 03:12:20 +0000182 else:
Guido van Rossum41360a41998-03-26 19:42:58 +0000183 return 1
Guido van Rossum152494a1996-12-20 03:12:20 +0000184
185def findtestdir():
186 if __name__ == '__main__':
Guido van Rossum41360a41998-03-26 19:42:58 +0000187 file = sys.argv[0]
Guido van Rossum152494a1996-12-20 03:12:20 +0000188 else:
Guido van Rossum41360a41998-03-26 19:42:58 +0000189 file = __file__
Guido van Rossum152494a1996-12-20 03:12:20 +0000190 testdir = os.path.dirname(file) or os.curdir
191 return testdir
192
193def count(n, word):
194 if n == 1:
Guido van Rossum41360a41998-03-26 19:42:58 +0000195 return "%d %s" % (n, word)
Guido van Rossum152494a1996-12-20 03:12:20 +0000196 else:
Guido van Rossum41360a41998-03-26 19:42:58 +0000197 return "%d %ss" % (n, word)
Guido van Rossum152494a1996-12-20 03:12:20 +0000198
199class Compare:
200
201 def __init__(self, filename):
Guido van Rossum41360a41998-03-26 19:42:58 +0000202 self.fp = open(filename, 'r')
Guido van Rossum152494a1996-12-20 03:12:20 +0000203
204 def write(self, data):
Guido van Rossum41360a41998-03-26 19:42:58 +0000205 expected = self.fp.read(len(data))
206 if data <> expected:
207 raise test_support.TestFailed, \
208 'Writing: '+`data`+', expected: '+`expected`
Guido van Rossum152494a1996-12-20 03:12:20 +0000209
Guido van Rossume87ed5f1998-04-23 13:33:21 +0000210 def writelines(self, listoflines):
211 map(self.write, listoflines)
212
Guido van Rossum75fce301997-07-17 14:51:37 +0000213 def flush(self):
Guido van Rossum41360a41998-03-26 19:42:58 +0000214 pass
Guido van Rossum75fce301997-07-17 14:51:37 +0000215
Guido van Rossum152494a1996-12-20 03:12:20 +0000216 def close(self):
Guido van Rossum41360a41998-03-26 19:42:58 +0000217 leftover = self.fp.read()
218 if leftover:
219 raise test_support.TestFailed, 'Unread: '+`leftover`
220 self.fp.close()
Guido van Rossum152494a1996-12-20 03:12:20 +0000221
222 def isatty(self):
Guido van Rossum41360a41998-03-26 19:42:58 +0000223 return 0
Guido van Rossum152494a1996-12-20 03:12:20 +0000224
225if __name__ == '__main__':
Guido van Rossume8387011997-08-14 19:40:34 +0000226 sys.exit(main())