blob: 21d35cfd748b932d0c992a1f5aa36e66281b9bcb [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 Rossum152494a1996-12-20 03:12:20 +000075 if exclude:
Guido van Rossum41360a41998-03-26 19:42:58 +000076 nottests[:0] = args
77 args = []
Guido van Rossum6fd83b71998-08-01 17:04:08 +000078 tests = tests or args or findtests()
Guido van Rossum41360a41998-03-26 19:42:58 +000079 test_support.verbose = verbose # Tell tests to be moderately quiet
Guido van Rossum152494a1996-12-20 03:12:20 +000080 for test in tests:
Guido van Rossum41360a41998-03-26 19:42:58 +000081 if not quiet:
82 print test
Guido van Rossum6fd83b71998-08-01 17:04:08 +000083 ok = runtest(test, generate, verbose, testdir)
Guido van Rossum41360a41998-03-26 19:42:58 +000084 if ok > 0:
85 good.append(test)
86 elif ok == 0:
87 bad.append(test)
88 else:
89 if not quiet:
90 print "test", test,
91 print "skipped -- an optional feature could not be imported"
92 skipped.append(test)
Guido van Rossum152494a1996-12-20 03:12:20 +000093 if good and not quiet:
Guido van Rossum41360a41998-03-26 19:42:58 +000094 if not bad and not skipped and len(good) > 1:
95 print "All",
96 print count(len(good), "test"), "OK."
Guido van Rossum152494a1996-12-20 03:12:20 +000097 if bad:
Guido van Rossum41360a41998-03-26 19:42:58 +000098 print count(len(bad), "test"), "failed:",
99 print string.join(bad)
Guido van Rossum152494a1996-12-20 03:12:20 +0000100 if skipped and not quiet:
Guido van Rossum41360a41998-03-26 19:42:58 +0000101 print count(len(skipped), "test"), "skipped:",
102 print string.join(skipped)
Guido van Rossume8387011997-08-14 19:40:34 +0000103 return len(bad) > 0
Guido van Rossum152494a1996-12-20 03:12:20 +0000104
Guido van Rossum6fd83b71998-08-01 17:04:08 +0000105STDTESTS = [
Guido van Rossum152494a1996-12-20 03:12:20 +0000106 'test_grammar',
107 'test_opcodes',
108 'test_operations',
109 'test_builtin',
110 'test_exceptions',
111 'test_types',
112 ]
113
Guido van Rossum6fd83b71998-08-01 17:04:08 +0000114NOTTESTS = [
Guido van Rossum152494a1996-12-20 03:12:20 +0000115 'test_support',
116 'test_b1',
117 'test_b2',
118 ]
119
Guido van Rossum6fd83b71998-08-01 17:04:08 +0000120def findtests(testdir=None, stdtests=STDTESTS, nottests=NOTTESTS):
Guido van Rossum152494a1996-12-20 03:12:20 +0000121 """Return a list of all applicable test modules."""
Guido van Rossum6fd83b71998-08-01 17:04:08 +0000122 if not testdir: testdir = findtestdir()
Guido van Rossum152494a1996-12-20 03:12:20 +0000123 names = os.listdir(testdir)
124 tests = []
125 for name in names:
Guido van Rossum41360a41998-03-26 19:42:58 +0000126 if name[:5] == "test_" and name[-3:] == ".py":
127 modname = name[:-3]
128 if modname not in stdtests and modname not in nottests:
129 tests.append(modname)
Guido van Rossum152494a1996-12-20 03:12:20 +0000130 tests.sort()
131 return stdtests + tests
132
Guido van Rossum6fd83b71998-08-01 17:04:08 +0000133def runtest(test, generate, verbose, testdir = None):
134 """Run a single test.
135 test -- the name of the test
136 generate -- if true, generate output, instead of running the test
137 and comparing it to a previously created output file
138 verbose -- if true, print more messages
139 testdir -- test directory
140 """
Guido van Rossum152494a1996-12-20 03:12:20 +0000141 test_support.unload(test)
Guido van Rossum6fd83b71998-08-01 17:04:08 +0000142 if not testdir: testdir = findtestdir()
Guido van Rossum152494a1996-12-20 03:12:20 +0000143 outputdir = os.path.join(testdir, "output")
144 outputfile = os.path.join(outputdir, test)
145 try:
Guido van Rossum41360a41998-03-26 19:42:58 +0000146 if generate:
147 cfp = open(outputfile, "w")
148 elif verbose:
149 cfp = sys.stdout
150 else:
151 cfp = Compare(outputfile)
Guido van Rossum152494a1996-12-20 03:12:20 +0000152 except IOError:
Guido van Rossum41360a41998-03-26 19:42:58 +0000153 cfp = None
154 print "Warning: can't open", outputfile
Guido van Rossum152494a1996-12-20 03:12:20 +0000155 try:
Guido van Rossum41360a41998-03-26 19:42:58 +0000156 save_stdout = sys.stdout
157 try:
158 if cfp:
159 sys.stdout = cfp
160 print test # Output file starts with test name
161 __import__(test, globals(), locals(), [])
162 finally:
163 sys.stdout = save_stdout
Guido van Rossum152494a1996-12-20 03:12:20 +0000164 except ImportError, msg:
Guido van Rossum41360a41998-03-26 19:42:58 +0000165 return -1
Guido van Rossum4e8ef5f1997-10-20 23:46:54 +0000166 except KeyboardInterrupt, v:
Guido van Rossum41360a41998-03-26 19:42:58 +0000167 raise KeyboardInterrupt, v, sys.exc_info()[2]
Guido van Rossum152494a1996-12-20 03:12:20 +0000168 except test_support.TestFailed, msg:
Guido van Rossum41360a41998-03-26 19:42:58 +0000169 print "test", test, "failed --", msg
170 return 0
Guido van Rossum9e48b271997-07-16 01:56:13 +0000171 except:
Guido van Rossum41360a41998-03-26 19:42:58 +0000172 type, value = sys.exc_info()[:2]
173 print "test", test, "crashed --", type, ":", value
174 if verbose:
175 traceback.print_exc(file=sys.stdout)
176 return 0
Guido van Rossum152494a1996-12-20 03:12:20 +0000177 else:
Guido van Rossum41360a41998-03-26 19:42:58 +0000178 return 1
Guido van Rossum152494a1996-12-20 03:12:20 +0000179
180def findtestdir():
181 if __name__ == '__main__':
Guido van Rossum41360a41998-03-26 19:42:58 +0000182 file = sys.argv[0]
Guido van Rossum152494a1996-12-20 03:12:20 +0000183 else:
Guido van Rossum41360a41998-03-26 19:42:58 +0000184 file = __file__
Guido van Rossum152494a1996-12-20 03:12:20 +0000185 testdir = os.path.dirname(file) or os.curdir
186 return testdir
187
188def count(n, word):
189 if n == 1:
Guido van Rossum41360a41998-03-26 19:42:58 +0000190 return "%d %s" % (n, word)
Guido van Rossum152494a1996-12-20 03:12:20 +0000191 else:
Guido van Rossum41360a41998-03-26 19:42:58 +0000192 return "%d %ss" % (n, word)
Guido van Rossum152494a1996-12-20 03:12:20 +0000193
194class Compare:
195
196 def __init__(self, filename):
Guido van Rossum41360a41998-03-26 19:42:58 +0000197 self.fp = open(filename, 'r')
Guido van Rossum152494a1996-12-20 03:12:20 +0000198
199 def write(self, data):
Guido van Rossum41360a41998-03-26 19:42:58 +0000200 expected = self.fp.read(len(data))
201 if data <> expected:
202 raise test_support.TestFailed, \
203 'Writing: '+`data`+', expected: '+`expected`
Guido van Rossum152494a1996-12-20 03:12:20 +0000204
Guido van Rossume87ed5f1998-04-23 13:33:21 +0000205 def writelines(self, listoflines):
206 map(self.write, listoflines)
207
Guido van Rossum75fce301997-07-17 14:51:37 +0000208 def flush(self):
Guido van Rossum41360a41998-03-26 19:42:58 +0000209 pass
Guido van Rossum75fce301997-07-17 14:51:37 +0000210
Guido van Rossum152494a1996-12-20 03:12:20 +0000211 def close(self):
Guido van Rossum41360a41998-03-26 19:42:58 +0000212 leftover = self.fp.read()
213 if leftover:
214 raise test_support.TestFailed, 'Unread: '+`leftover`
215 self.fp.close()
Guido van Rossum152494a1996-12-20 03:12:20 +0000216
217 def isatty(self):
Guido van Rossum41360a41998-03-26 19:42:58 +0000218 return 0
Guido van Rossum152494a1996-12-20 03:12:20 +0000219
220if __name__ == '__main__':
Guido van Rossume8387011997-08-14 19:40:34 +0000221 sys.exit(main())