blob: 236c927e87ae7ecf08123ad42ddec2123ca399f7 [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
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
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.
19"""
20
21import sys
22import string
23import os
24import getopt
25
26import test_support
27
28def 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
77stdtests = [
78 'test_grammar',
79 'test_opcodes',
80 'test_operations',
81 'test_builtin',
82 'test_exceptions',
83 'test_types',
84 ]
85
86nottests = [
87 'test_support',
88 'test_b1',
89 'test_b2',
90 ]
91
92def 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
105def 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
135def 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
143def count(n, word):
144 if n == 1:
145 return "%d %s" % (n, word)
146 else:
147 return "%d %ss" % (n, word)
148
149class 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
169if __name__ == '__main__':
170 main()