5 This will find all modules whose name is "test_*" in the test
6 directory, and run them. Various command line options provide
11 -v: verbose -- run tests in verbose mode with output to stdout
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 -s: single -- run only a single test (see below)
16 -r: random -- randomize test execution order
17 -f: fromfile -- read names of tests to run from a file (see below)
18 -l: findleaks -- if GC is available detect tests that leak memory
19 -u: use -- specify which special resource intensive tests to run
20 -h: help -- print this text and exit
21 -t: threshold -- call gc.set_threshold(N)
23 If non-option arguments are present, they are names for tests to run,
24 unless -x is given, in which case they are names for tests not to run.
25 If no test names are given, all tests are run.
27 -v is incompatible with -g and does not compare test output files.
29 -s means to run only a single test and exit. This is useful when
30 doing memory analysis on the Python interpreter (which tend to consume
31 too many resources to run the full regression test non-stop). The
32 file /tmp/pynexttest is read to find the next test to run. If this
33 file is missing, the first test_*.py file in testdir or on the command
34 line is used. (actually tempfile.gettempdir() is used instead of
37 -f reads the names of tests from the file given as f's argument, one
38 or more test names per line. Whitespace is ignored. Blank lines and
39 lines beginning with '#' are ignored. This is especially useful for
40 whittling down failures involving interactions among tests.
42 -u is used to specify which special resource intensive tests to run,
43 such as those requiring large file support or network connectivity.
44 The argument is a comma-separated list of words indicating the
45 resources to test. Currently only the following are defined:
47 all - Enable all special resources.
49 curses - Tests that use curses and will modify the terminal's
50 state and output modes.
52 largefile - It is okay to run some test that may create huge
53 files. These tests can take a long time and may
54 consume >2GB of disk space temporarily.
56 network - It is okay to run tests that use external network
57 resource, e.g. testing SSL support for sockets.
70 RESOURCE_NAMES
= ('curses', 'largefile', 'network')
73 def usage(code
, msg
=''):
79 def main(tests
=None, testdir
=None, verbose
=0, quiet
=0, generate
=0,
80 exclude
=0, single
=0, randomize
=0, fromfile
=None, findleaks
=0,
82 """Execute a test suite.
84 This also parses command-line options and modifies its behavior
87 tests -- a list of strings containing test names (optional)
88 testdir -- the directory in which to look for tests (optional)
90 Users other than the Python test suite will certainly want to
91 specify testdir; if it's omitted, the directory containing the
92 Python test suite is searched for.
94 If the tests argument is omitted, the tests listed on the
95 command-line will be used. If that's empty, too, then all *.py
96 files beginning with test_ will be used.
98 The other default arguments (verbose, quiet, generate, exclude,
99 single, randomize, findleaks, and use_resources) allow programmers
100 calling main() directly to set the values that would normally be
101 set by flags on the command line.
105 test_support
.record_original_stdout(sys
.stdout
)
107 opts
, args
= getopt
.getopt(sys
.argv
[1:], 'hvgqxsrf:lu:t:',
108 ['help', 'verbose', 'quiet', 'generate',
109 'exclude', 'single', 'random', 'fromfile',
110 'findleaks', 'use=', 'threshold='])
111 except getopt
.error
, msg
:
115 if use_resources
is None:
118 if o
in ('-h', '--help'):
120 elif o
in ('-v', '--verbose'):
122 elif o
in ('-q', '--quiet'):
125 elif o
in ('-g', '--generate'):
127 elif o
in ('-x', '--exclude'):
129 elif o
in ('-s', '--single'):
131 elif o
in ('-r', '--randomize'):
133 elif o
in ('-f', '--fromfile'):
135 elif o
in ('-l', '--findleaks'):
137 elif o
in ('-t', '--threshold'):
139 gc
.set_threshold(int(a
))
140 elif o
in ('-u', '--use'):
141 u
= [x
.lower() for x
in a
.split(',')]
144 use_resources
= RESOURCE_NAMES
146 if r
not in RESOURCE_NAMES
:
147 usage(1, 'Invalid -u/--use option: ' + a
)
148 if r
not in use_resources
:
149 use_resources
.append(r
)
150 if generate
and verbose
:
151 usage(2, "-g and -v don't go together!")
152 if single
and fromfile
:
153 usage(2, "-s and -f don't go together!")
163 print 'No GC available, disabling findleaks.'
166 # Uncomment the line below to report garbage that is not
167 # freeable by reference counting alone. By default only
168 # garbage that is not collectable by the GC is reported.
169 #gc.set_debug(gc.DEBUG_SAVEALL)
173 from tempfile
import gettempdir
174 filename
= os
.path
.join(gettempdir(), 'pynexttest')
176 fp
= open(filename
, 'r')
177 next
= fp
.read().strip()
187 guts
= line
.split() # assuming no test has whitespace in its name
188 if guts
and not guts
[0].startswith('#'):
192 # Strip .py extensions.
194 args
= map(removepy
, args
)
196 tests
= map(removepy
, tests
)
198 stdtests
= STDTESTS
[:]
199 nottests
= NOTTESTS
[:]
206 tests
= tests
or args
or findtests(testdir
, stdtests
, nottests
)
210 random
.shuffle(tests
)
211 test_support
.verbose
= verbose
# Tell tests to be moderately quiet
212 test_support
.use_resources
= use_resources
213 save_modules
= sys
.modules
.keys()
217 ok
= runtest(test
, generate
, verbose
, quiet
, testdir
)
227 print "Warning: test created", len(gc
.garbage
),
228 print "uncollectable object(s)."
229 # move the uncollectable objects somewhere so we don't see
231 found_garbage
.extend(gc
.garbage
)
233 # Unload the newly imported modules (best effort finalization)
234 for module
in sys
.modules
.keys():
235 if module
not in save_modules
and module
.startswith("test."):
236 test_support
.unload(module
)
238 # The lists won't be sorted if running with -r
243 if good
and not quiet
:
244 if not bad
and not skipped
and len(good
) > 1:
246 print count(len(good
), "test"), "OK."
248 print "CAUTION: stdout isn't compared in verbose mode: a test"
249 print "that passes in verbose mode may fail without it."
251 print count(len(bad
), "test"), "failed:"
253 if skipped
and not quiet
:
254 print count(len(skipped
), "test"), "skipped:"
260 surprise
= _Set(skipped
) - e
.getexpected()
262 print count(len(surprise
), "skip"), \
263 "unexpected on", plat
+ ":"
266 print "Those skips are all expected on", plat
+ "."
268 print "Ask someone to teach regrtest.py about which tests are"
269 print "expected to get skipped on", plat
+ "."
272 alltests
= findtests(testdir
, stdtests
, nottests
)
273 for i
in range(len(alltests
)):
274 if tests
[0] == alltests
[i
]:
275 if i
== len(alltests
) - 1:
278 fp
= open(filename
, 'w')
279 fp
.write(alltests
[i
+1] + '\n')
285 sys
.exit(len(bad
) > 0)
306 def findtests(testdir
=None, stdtests
=STDTESTS
, nottests
=NOTTESTS
):
307 """Return a list of all applicable test modules."""
308 if not testdir
: testdir
= findtestdir()
309 names
= os
.listdir(testdir
)
312 if name
[:5] == "test_" and name
[-3:] == os
.extsep
+"py":
314 if modname
not in stdtests
and modname
not in nottests
:
315 tests
.append(modname
)
317 return stdtests
+ tests
319 def runtest(test
, generate
, verbose
, quiet
, testdir
= None):
320 """Run a single test.
321 test -- the name of the test
322 generate -- if true, generate output, instead of running the test
323 and comparing it to a previously created output file
324 verbose -- if true, print more messages
325 quiet -- if true, don't print 'skipped' messages (probably redundant)
326 testdir -- test directory
328 test_support
.unload(test
)
329 if not testdir
: testdir
= findtestdir()
330 outputdir
= os
.path
.join(testdir
, "output")
331 outputfile
= os
.path
.join(outputdir
, test
)
335 cfp
= StringIO
.StringIO()
337 save_stdout
= sys
.stdout
341 print test
# Output file starts with test name
342 the_module
= __import__(test
, globals(), locals(), [])
343 # Most tests run to completion simply as a side-effect of
344 # being imported. For the benefit of tests that can't run
345 # that way (like test_threaded_import), explicitly invoke
346 # their test_main() function (if it exists).
347 indirect_test
= getattr(the_module
, "test_main", None)
348 if indirect_test
is not None:
351 sys
.stdout
= save_stdout
352 except (ImportError, test_support
.TestSkipped
), msg
:
354 print "test", test
, "skipped --", msg
356 except KeyboardInterrupt:
358 except test_support
.TestFailed
, msg
:
359 print "test", test
, "failed --", msg
362 type, value
= sys
.exc_info()[:2]
363 print "test", test
, "crashed --", str(type) + ":", value
365 traceback
.print_exc(file=sys
.stdout
)
370 output
= cfp
.getvalue()
372 if output
== test
+ "\n":
373 if os
.path
.exists(outputfile
):
374 # Write it since it already exists (and the contents
375 # may have changed), but let the user know it isn't
377 print "output file", outputfile
, \
378 "is no longer needed; consider removing it"
380 # We don't need it, so don't create it.
382 fp
= open(outputfile
, "w")
386 if os
.path
.exists(outputfile
):
387 fp
= open(outputfile
, "r")
391 expected
= test
+ "\n"
392 if output
== expected
:
394 print "test", test
, "produced unexpected output:"
395 reportdiff(expected
, output
)
398 def reportdiff(expected
, output
):
401 a
= expected
.splitlines(1)
402 b
= output
.splitlines(1)
403 sm
= difflib
.SequenceMatcher(a
=a
, b
=b
)
404 tuples
= sm
.get_opcodes()
407 # x0:x1 are 0-based slice indices; convert to 1-based line indices.
410 return "line " + str(x0
)
412 return "lines %d-%d" % (x0
, x1
)
414 for op
, a0
, a1
, b0
, b1
in tuples
:
419 print "***", pair(a0
, a1
), "of expected output missing:"
420 for line
in a
[a0
:a1
]:
423 elif op
== 'replace':
424 print "*** mismatch between", pair(a0
, a1
), "of expected", \
425 "output and", pair(b0
, b1
), "of actual output:"
426 for line
in difflib
.ndiff(a
[a0
:a1
], b
[b0
:b1
]):
430 print "***", pair(b0
, b1
), "of actual output doesn't appear", \
431 "in expected output after line", str(a1
)+":"
432 for line
in b
[b0
:b1
]:
436 print "get_opcodes() returned bad tuple?!?!", (op
, a0
, a1
, b0
, b1
)
441 if __name__
== '__main__':
445 testdir
= os
.path
.dirname(file) or os
.curdir
449 if name
.endswith(os
.extsep
+ "py"):
455 return "%d %s" % (n
, word
)
457 return "%d %ss" % (n
, word
)
459 def printlist(x
, width
=70, indent
=4):
460 """Print the elements of a sequence to stdout.
462 Optional arg width (default 70) is the maximum line length.
463 Optional arg indent (default 4) is the number of blanks with which to
468 for one
in map(str, x
):
469 w
= len(line
) + len(one
)
477 line
= ' ' * indent
+ one
480 if len(line
) > indent
:
484 def __init__(self
, seq
=[]):
485 data
= self
.data
= {}
490 return len(self
.data
)
492 def __sub__(self
, other
):
493 "Return set of all elements in self not in other."
495 data
= result
.data
= self
.data
.copy()
502 return iter(self
.data
)
504 def tolist(self
, sorted=1):
505 "Return _Set elements as a list."
506 data
= self
.data
.keys()
511 # Map sys.platform to a string containing the basenames of tests
512 # expected to be skipped on that platform.
664 test_threadedtempfile
754 class _ExpectedSkips
:
757 if sys
.platform
in _expectations
:
758 s
= _expectations
[sys
.platform
]
759 self
.expected
= _Set(s
.split())
763 "Return true iff _ExpectedSkips knows about the current platform."
766 def getexpected(self
):
767 """Return set of test names we expect to skip on current platform.
769 self.isvalid() must be true.
772 assert self
.isvalid()
775 if __name__
== '__main__':