# HG changeset patch
# User Mitesh Patel <qed777@gmail.com>
# Date 1260769644 28800
# Node ID 9f65e5bf20218471be2096cc2448cd53d29cef8f
# Parent 505395136942ebc633b23694e16d9644ce9fe127
#7650/doctest: Doctest option to force "library code" test mode
diff --git a/sage-doctest b/sage-doctest
a
|
b
|
def is_64bit(): |
57 | 57 | ###################################################### |
58 | 58 | DOT_SAGE = os.environ['DOT_SAGE'] |
59 | 59 | if 'SAGE_TESTDIR' not in os.environ or os.environ['SAGE_TESTDIR'] is "": |
60 | | SAGE_TESTDIR = DOT_SAGE + "/tmp" |
| 60 | SAGE_TESTDIR = os.path.join(DOT_SAGE, "tmp") |
61 | 61 | else: |
62 | 62 | SAGE_TESTDIR = os.environ['SAGE_TESTDIR'] |
63 | 63 | |
… |
… |
def delete_tmpfiles(): |
75 | 75 | ###################################################### |
76 | 76 | SAGE_ROOT = os.environ["SAGE_ROOT"] |
77 | 77 | LD = os.environ["LD_LIBRARY_PATH"] |
78 | | os.environ["LD_LIBRARY_PATH"] = SAGE_ROOT + "/local/lib:" + LD |
79 | | os.environ["PYTHONPATH"]=SAGE_ROOT + "/local/lib/python/site-packages" |
| 78 | os.environ["LD_LIBRARY_PATH"] = os.path.join(SAGE_ROOT, 'local', |
| 79 | 'lib') + ":" + LD |
| 80 | os.environ["PYTHONPATH"] = os.path.join(SAGE_ROOT, 'local', 'lib', 'python', |
| 81 | 'site-packages') |
80 | 82 | if os.environ.has_key('SAGE_PATH'): |
81 | | os.environ["PYTHONPATH"]= os.environ["PYTHONPATH"]+ ':'+os.environ['SAGE_PATH'] |
| 83 | os.environ["PYTHONPATH"] = os.environ["PYTHONPATH"] + ':' + os.environ['SAGE_PATH'] |
82 | 84 | |
83 | 85 | |
84 | 86 | ###################################################### |
85 | 87 | # Custom flags for the valgrind modes |
86 | 88 | ###################################################### |
| 89 | logfile = ' --log-file=' + os.path.join('$HOME', '.sage', 'valgrind', 'sage-%s') + ' ' |
87 | 90 | try: |
88 | | SAGE_MEMCHECK_FLAGS=os.environ['SAGE_MEMCHECK_FLAGS'] |
| 91 | SAGE_MEMCHECK_FLAGS = os.environ['SAGE_MEMCHECK_FLAGS'] |
89 | 92 | print SAGE_MEMCHECK_FLAGS |
90 | 93 | except: |
91 | | SAGE_MEMCHECK_FLAGS=" --leak-resolution=high --log-file=$HOME/.sage/valgrind/sage-memcheck.%p --leak-check=full --num-callers=25 --suppressions=$SAGE_LOCAL/lib/valgrind/sage.supp " |
| 94 | suppfile = os.path.join('$SAGE_LOCAL', 'lib', 'valgrind', 'sage.supp') |
| 95 | SAGE_MEMCHECK_FLAGS = " --leak-resolution=high %s --leak-check=full --num-callers=25 --suppressions=%s " % (logfile % 'memcheck.%p', suppfile) |
92 | 96 | |
93 | 97 | try: |
94 | | SAGE_MASSIF_FLAGS=os.environ['SAGE_MASSIF_FLAGS'] |
| 98 | SAGE_MASSIF_FLAGS = os.environ['SAGE_MASSIF_FLAGS'] |
95 | 99 | except: |
96 | | SAGE_MASSIF_FLAGS=" --depth=6 --log-file=$HOME/.sage/valgrind/sage-massif.%p " |
| 100 | SAGE_MASSIF_FLAGS = " --depth=6 " + (logfile % 'massif.%p') |
97 | 101 | |
98 | 102 | try: |
99 | | SAGE_CALLGRIND_FLAGS=os.environ['SAGE_CALLGRIND_FLAGS'] |
| 103 | SAGE_CALLGRIND_FLAGS = os.environ['SAGE_CALLGRIND_FLAGS'] |
100 | 104 | except: |
101 | | SAGE_CALLGRIND_FLAGS = " --log-file=$HOME/.sage/valgrind/sage-callgrind.%p " |
| 105 | SAGE_CALLGRIND_FLAGS = logfile % 'callgrind.%p' |
102 | 106 | |
103 | 107 | try: |
104 | | SAGE_CACHEGRIND_FLAGS=os.environ['SAGE_CACHEGRIND_FLAGS'] |
| 108 | SAGE_CACHEGRIND_FLAGS = os.environ['SAGE_CACHEGRIND_FLAGS'] |
105 | 109 | except: |
106 | | SAGE_CACHEGRIND_FLAGS=" --log-file=$HOME/.sage/valgrind/sage-cachegrind.%p " |
| 110 | SAGE_CALLGRIND_FLAGS = logfile % 'cachegrind.%p' |
107 | 111 | |
108 | 112 | try: |
109 | | SAGE_OMEGA_FLAGS=os.environ['SAGE_OMEGA_FLAGS'] |
| 113 | SAGE_OMEGA_FLAGS = os.environ['SAGE_OMEGA_FLAGS'] |
110 | 114 | except: |
111 | | SAGE_OMEGA_FLAGS = " --log-file=$HOME/.sage/valgrind/sage-omega.%p " |
| 115 | SAGE_OMEGA_FLAGS = logfile % 'omega.%p' |
112 | 116 | |
113 | 117 | ###################################################### |
114 | 118 | # The Python binary |
… |
… |
def new_index(n): |
148 | 152 | return n |
149 | 153 | |
150 | 154 | def test_code(filename): |
151 | | dict = { 'DIR' : repr('%s/local/bin' % SAGE_ROOT), |
| 155 | dict = { 'DIR' : repr(os.path.join(SAGE_ROOT, 'local', 'bin')), |
152 | 156 | 'FILENAME' : repr(filename), |
153 | 157 | 'OUTPUT_FILENAME' : repr(filename + '.timeit.sobj'), |
154 | 158 | 'TIMEIT' : do_timeit, # global |
… |
… |
def change_warning_output(file): |
404 | 408 | if not library_code: |
405 | 409 | if ext in ['.py', '.pyx','.spyx']: |
406 | 410 | os.system('cp -f %s %s' % (file_name, SAGE_TESTDIR)) |
407 | | tmpfiles.append('%s/%s%s' % (SAGE_TESTDIR, name, ext)) |
| 411 | tmpfiles.append(os.path.join(SAGE_TESTDIR, '%s%s' % (name, ext))) |
408 | 412 | if ext == '.py': |
409 | 413 | s += "from %s import *\n\n" % name |
410 | 414 | else: |
… |
… |
def change_warning_output(file): |
412 | 416 | elif ext == '.sage': |
413 | 417 | os.system('sage -preparse %s' % file_name) |
414 | 418 | os.system('mv -f %s.py %s' % (base, SAGE_TESTDIR)) |
415 | | tmpfiles.append('%s/%s.py' % (SAGE_TESTDIR, name)) |
| 419 | tmpfiles.append(os.path.join(SAGE_TESTDIR, name + '.py')) |
416 | 420 | s += "from %s import *\n\n" % (name) |
417 | 421 | if ext in ['.py', '.sage']: |
418 | | tmpfiles.append('%s/%s.pyc' % (SAGE_TESTDIR, name)) |
| 422 | tmpfiles.append(os.path.join(SAGE_TESTDIR, name + '.pyc')) |
419 | 423 | |
420 | 424 | n = 0 |
421 | 425 | while True: |
… |
… |
def test_file(file, library_code): |
589 | 593 | if len(s) == 0: |
590 | 594 | sys.exit(0) |
591 | 595 | |
592 | | f = "%s/.doctest_%s.py"%(SAGE_TESTDIR,name) |
| 596 | f = os.path.join(SAGE_TESTDIR, ".doctest_%s.py" % name) |
593 | 597 | |
594 | 598 | open(f,"w").write(s) |
595 | 599 | tmpfiles.append(f) |
… |
… |
def test_file(file, library_code): |
610 | 614 | if omega: |
611 | 615 | cmd = "valgrind --tool=exp-omega " + SAGE_OMEGA_FLAGS + cmd |
612 | 616 | |
613 | | VALGRIND = '%s/valgrind/'%DOT_SAGE |
| 617 | VALGRIND = os.path.join(DOT_SAGE, 'valgrind') |
614 | 618 | if not os.path.exists(VALGRIND): |
615 | 619 | os.makedirs(VALGRIND) |
616 | 620 | |
… |
… |
if __name__ == '__main__': |
742 | 746 | massif = has_opt('massif') |
743 | 747 | cachegrind = has_opt('cachegrind') |
744 | 748 | omega = has_opt('omega') |
| 749 | force_lib = has_opt('force_lib') |
745 | 750 | random_order = parse_rand() |
746 | 751 | only_optional, only_optional_tags = parse_only_opt() |
747 | 752 | if long_time: |
… |
… |
if __name__ == '__main__': |
751 | 756 | if argv[1][0] == '-': |
752 | 757 | usage() |
753 | 758 | |
| 759 | ext = os.path.splitext(argv[1])[1] |
| 760 | |
754 | 761 | library_code = True |
755 | | ext = os.path.splitext(argv[1])[1] |
756 | | if ext in ['.spyx', '.sage'] or \ |
757 | | not (os.path.realpath(os.path.join(SAGE_ROOT, 'devel')) in os.path.realpath(argv[1])): |
| 762 | dev_path = os.path.realpath(os.path.join(SAGE_ROOT, 'devel')) |
| 763 | our_path = os.path.realpath(argv[1]) |
| 764 | |
| 765 | if not force_lib and (ext in ['.spyx', '.sage'] or |
| 766 | not dev_path in our_path): |
758 | 767 | library_code = False |
759 | 768 | |
760 | 769 | try: |
diff --git a/sage-maketest b/sage-maketest
a
|
b
|
fi |
23 | 23 | # (We do this all in a single run of "sage -t" so we get a single summary.) |
24 | 24 | # We test three subdirectories of doc/, rather than testing the |
25 | 25 | # entirety of doc/, so that we can skip doc/output. |
26 | | "$SAGE_ROOT"/sage -t "$@" "$SAGE_ROOT"/devel/sage/doc/common "$SAGE_ROOT"/devel/sage/doc/en "$SAGE_ROOT"/devel/sage/doc/fr "$SAGE_ROOT"/devel/sage/sage 2>&1 | tee -a "$SAGE_TEST_LOG" |
| 26 | "$SAGE_ROOT"/sage -t -sagenb "$@" "$SAGE_ROOT"/devel/sage/doc/common "$SAGE_ROOT"/devel/sage/doc/en "$SAGE_ROOT"/devel/sage/doc/fr "$SAGE_ROOT"/devel/sage/sage 2>&1 | tee -a "$SAGE_TEST_LOG" |
27 | 27 | |
28 | 28 | # Print the small summary report for dsage unit tests, if necessary. |
29 | 29 | # TODO -- skip this for now. |
diff --git a/sage-ptest b/sage-ptest
a
|
b
|
except: |
17 | 17 | numglobaliteration = 1 |
18 | 18 | |
19 | 19 | SAGE_ROOT = os.environ['SAGE_ROOT'] |
20 | | BUILD_DIR = os.path.realpath(SAGE_ROOT + "/devel/sage/build") |
| 20 | SAGE_SITE = os.path.realpath(os.path.join(os.environ['SAGE_LOCAL'], |
| 21 | 'lib', 'python', 'site-packages')) |
| 22 | BUILD_DIR = os.path.realpath(os.path.join(SAGE_ROOT, 'devel', 'sage', 'build')) |
21 | 23 | |
22 | 24 | print 'Global iterations: ' + str(numglobaliteration) |
23 | 25 | print 'File iterations: ' + str(numiteration) |
… |
… |
def skip(F): |
100 | 102 | if not os.path.exists(F): |
101 | 103 | return True |
102 | 104 | G = abspath(F) |
103 | | i = G.rfind('/') |
104 | | if os.path.exists('%s/nodoctest.py'%G[:i]): |
| 105 | i = G.rfind(os.path.sep) |
| 106 | if os.path.exists(os.path.join(G[:i], 'nodoctest.py')): |
105 | 107 | printmutex.acquire() |
106 | 108 | print "%s (skipping) -- nodoctest.py file in directory"%abs(F) |
107 | 109 | printmutex.release() |
108 | 110 | return True |
109 | 111 | filenm = os.path.split(F)[1] |
110 | | if filenm[0] == '.' or '/.' in G.lstrip('/.') or \ |
111 | | 'nodoctest' in open(G).read()[:50]: |
| 112 | if (filenm[0] == '.' or (os.path.sep + '.' in G.lstrip(os.path.sep + '.')) |
| 113 | or 'nodoctest' in open(G).read()[:50]): |
112 | 114 | return True |
113 | | if G.find('doc/output') != -1: |
| 115 | if G.find(os.path.join('doc', 'output')) != -1: |
114 | 116 | return True |
115 | 117 | if not (os.path.splitext(F)[1] in ['.py', '.pyx', '.tex', '.pxi', '.sage', '.rst']): |
116 | 118 | return True |
… |
… |
def test_file(F): |
122 | 124 | """ |
123 | 125 | outfile = tempfile.NamedTemporaryFile() |
124 | 126 | base, ext = os.path.splitext(F) |
| 127 | |
125 | 128 | if use_sage_only or ext == '.sage': |
126 | 129 | cmd = 'doctest_tex ' + opts |
127 | 130 | elif ext in ['.py', '.pyx', '.tex', '.pxi', '.rst']: |
128 | | cmd = 'doctest '+opts |
| 131 | cmd = 'doctest ' + opts |
| 132 | if SAGE_SITE in os.path.realpath(F) and not '-force_lib' in cmd: |
| 133 | cmd += ' -force_lib' |
| 134 | |
129 | 135 | filestr = os.path.split(F)[1] |
130 | 136 | for i in range(0,numiteration): |
131 | 137 | os.chdir(os.path.dirname(F)) |
132 | | s = 'bash -c "%s/local/bin/sage-%s %s > %s" ' %(SAGE_ROOT, cmd, filestr, outfile.name) |
| 138 | command = os.path.join(SAGE_ROOT, 'local', 'bin', 'sage-%s' % cmd) |
| 139 | s = 'bash -c "%s %s > %s" ' % (command, filestr, outfile.name) |
133 | 140 | try: |
134 | 141 | t = time.time() |
135 | 142 | ret = os.system(s) |
… |
… |
def populatefilelist(filelist): |
204 | 211 | continue |
205 | 212 | if not os.path.isabs(FF): |
206 | 213 | cwd = os.getcwd() |
207 | | files.append(cwd + '/' + FF) |
| 214 | files.append(os.path.join(cwd, FF)) |
208 | 215 | else: |
209 | 216 | files.append(FF) |
210 | 217 | continue |
… |
… |
def populatefilelist(filelist): |
228 | 235 | continue |
229 | 236 | files.append(appendstr) |
230 | 237 | for D in dirs: |
231 | | if '#' in D or '/notes' in D: |
| 238 | if '#' in D or (os.path.sep + 'notes' in D): |
232 | 239 | dirs.remove(D) |
233 | 240 | filemutex.release() |
234 | 241 | return 0 |
235 | 242 | |
236 | 243 | |
237 | | |
238 | | |
239 | | |
240 | | |
241 | | |
242 | | |
243 | | |
244 | | |
245 | 244 | for gr in range(0,numglobaliteration): |
246 | 245 | |
247 | 246 | try: |
… |
… |
for gr in range(0,numglobaliteration): |
261 | 260 | numthreads = 1 |
262 | 261 | infiles = argv[1:] |
263 | 262 | |
| 263 | if '-sagenb' in opts: |
| 264 | opts = opts.replace('--sagenb', '').replace('-sagenb', '') |
| 265 | |
| 266 | # Find SageNB's home. |
| 267 | from pkg_resources import Requirement, working_set |
| 268 | sagenb_loc = working_set.find(Requirement.parse('sagenb')).location |
| 269 | |
| 270 | # In case we're using setuptools' "develop" mode. |
| 271 | if not SAGE_SITE in sagenb_loc: |
| 272 | opts += ' -force_lib' |
| 273 | |
| 274 | infiles.append(os.path.join(sagenb_loc, 'sagenb')) |
| 275 | |
264 | 276 | if numthreads == 0: |
265 | 277 | # Set numthreads to be the number of processors, with a default |
266 | 278 | # maximum of 8. |
… |
… |
for gr in range(0,numglobaliteration): |
298 | 310 | filemutex = thread.allocate_lock() |
299 | 311 | printmutex = thread.allocate_lock() |
300 | 312 | #Pick a filename for the timing files -- long vs normal |
301 | | time_file_name = os.environ["SAGE_TESTDIR"]+"/" |
302 | 313 | if opts.count("-long"): |
303 | | time_file_name+=".ptest_timing_long" |
| 314 | time_file_name = os.path.join(os.environ["SAGE_TESTDIR"], |
| 315 | '.ptest_timing_long') |
304 | 316 | else: |
305 | | time_file_name+=".ptest_timing" |
| 317 | time_file_name = os.path.join(os.environ["SAGE_TESTDIR"], |
| 318 | '.ptest_timing') |
306 | 319 | time_dict = { } |
307 | 320 | try: |
308 | 321 | with open(time_file_name) as time_file: |
… |
… |
for gr in range(0,numglobaliteration): |
324 | 337 | failed = [] |
325 | 338 | |
326 | 339 | SAGE_ROOT=os.environ['SAGE_ROOT'] |
327 | | TMP=os.environ['SAGE_TESTDIR'] + "/tmp/test/" |
| 340 | TMP = os.path.join(os.environ['SAGE_TESTDIR'], 'tmp', 'test') |
328 | 341 | if not os.path.exists(TMP): |
329 | 342 | os.makedirs(TMP) |
330 | 343 | |
… |
… |
for gr in range(0,numglobaliteration): |
380 | 393 | print "-"*int(70) |
381 | 394 | |
382 | 395 | print "Total time for all tests: %.1f seconds"%(time.time() - t0) |
383 | | |
384 | | |
diff --git a/sage-test b/sage-test
a
|
b
|
def strip_automount_prefix(filename): |
41 | 41 | return filename |
42 | 42 | |
43 | 43 | |
44 | | SAGE_ROOT=os.environ['SAGE_ROOT'] |
| 44 | SAGE_ROOT = os.environ['SAGE_ROOT'] |
| 45 | SAGE_SITE = os.path.realpath(os.path.join(os.environ['SAGE_LOCAL'], |
| 46 | 'lib', 'python', 'site-packages')) |
| 47 | |
45 | 48 | if 'SAGE_TESTDIR' not in os.environ: |
46 | | os.environ['SAGE_TESTDIR'] = SAGE_ROOT + "/tmp" |
47 | | TMP=os.environ['SAGE_TESTDIR'] + "/tmp" |
| 49 | os.environ['SAGE_TESTDIR'] = os.path.join(SAGE_ROOT, "tmp") |
| 50 | TMP = os.path.join(os.environ['SAGE_TESTDIR'], "tmp") |
48 | 51 | if not os.path.exists(TMP): |
49 | 52 | os.makedirs(TMP) |
50 | 53 | |
… |
… |
def sage_test_command(f): |
56 | 59 | |
57 | 60 | def skip(F): |
58 | 61 | G = abspath(F) |
59 | | i = G.rfind('/') |
60 | | if os.path.exists('%s/nodoctest.py'%G[:i]): |
| 62 | i = G.rfind(os.sep) |
| 63 | if os.path.exists(os.path.join(G[:i], 'nodoctest.py')): |
61 | 64 | print "%s (skipping) -- nodoctest.py file in directory"%sage_test_command(F) |
62 | 65 | return True |
63 | 66 | |
64 | 67 | if 'nodoctest' in open(G).read()[:50]: |
65 | 68 | return True |
66 | | if G.find('doc/output') != -1: |
| 69 | if G.find(os.path.join('doc', 'output')) != -1: |
67 | 70 | return True |
68 | 71 | |
69 | 72 | sys.stdout.write("%-60s"%sage_test_command(F)+"\n") |
… |
… |
def test(F, cmd): |
77 | 80 | if skip(F): |
78 | 81 | return 0 |
79 | 82 | try: |
80 | | s = '%s/local/bin/sage-%s "%s"'%(SAGE_ROOT, cmd, F) |
| 83 | s = os.path.join(SAGE_ROOT, 'local', 'bin', |
| 84 | 'sage-%s' % cmd) + ' "%s"' % F |
81 | 85 | err = os.system(s) # need to catch control c by writing to a file and looking at it?? |
82 | 86 | except KeyboardInterrupt: |
83 | 87 | print "Keyboard Interrupt" |
… |
… |
def test(F, cmd): |
92 | 96 | |
93 | 97 | def test_file(F): |
94 | 98 | if not os.path.exists(F): |
95 | | if os.path.exists(os.environ["SAGE_ROOT"] + "/" + F): |
96 | | F = os.environ["SAGE_ROOT"] + "/" + F |
| 99 | if os.path.exists(os.path.join(SAGE_ROOT, F)): |
| 100 | F = os.path.join(SAGE_ROOT, F) |
97 | 101 | if not os.path.exists(F): |
98 | 102 | if F[:6] != "__test" and not F.endswith('.png'): |
99 | | print "ERROR: File %s/%s is missing"%(os.curdir,F) |
100 | | failed.append('%s/%s'%(os.curdir,F)) |
| 103 | print "ERROR: File %s is missing" % os.path.join(os.curdir, F) |
| 104 | failed.append(os.path.join(os.curdir, F)) |
101 | 105 | return 1 |
102 | 106 | |
| 107 | extra_opts = '' |
| 108 | if SAGE_SITE in os.path.realpath(F) and not '-force_lib' in opts: |
| 109 | extra_opts = ' -force_lib' |
| 110 | |
103 | 111 | base, ext = os.path.splitext(F) |
104 | 112 | if ext in ['.py', '.spyx', '.pyx', '.tex', '.pxi', '.sage', '.rst']: |
105 | | return test(F, 'doctest '+opts) |
| 113 | return test(F, 'doctest ' + opts + extra_opts) |
106 | 114 | elif os.path.isdir(F) and not (F[:1] == '.') \ |
107 | | and not '#' in F and not '/notes' in F: |
| 115 | and not '#' in F and not os.sep + 'notes' in F: |
108 | 116 | ld = os.listdir(F) |
109 | 117 | if not ('__nodoctest__' in ld): |
110 | 118 | for L in ld: |
111 | | k = test_file('%s/%s'%(F,L)) |
| 119 | k = test_file(os.path.join(F, L)) |
112 | 120 | return 0 |
113 | 121 | |
114 | 122 | files = argv[1:] |
| 123 | |
| 124 | if '-sagenb' in opts: |
| 125 | opts = opts.replace('--sagenb', '').replace('-sagenb', '') |
| 126 | |
| 127 | # Find SageNB's home. |
| 128 | from pkg_resources import Requirement, working_set |
| 129 | sagenb_loc = working_set.find(Requirement.parse('sagenb')).location |
| 130 | |
| 131 | # In case we're using setuptools' "develop" mode. |
| 132 | if not SAGE_SITE in sagenb_loc: |
| 133 | opts += ' -force_lib' |
| 134 | |
| 135 | files.append(os.path.join(sagenb_loc, 'sagenb')) |
| 136 | |
115 | 137 | if len(files) == 0: |
116 | 138 | print "Usage: sage -t [-verbose] [-long] [-optional] [-only-optional=list,of,tags] <files or directories>" |
117 | 139 | print "Test the docstrings in each listed Python or Cython file, and " |
… |
… |
if len(files) == 0: |
119 | 141 | print "all subdirectories of that directory." |
120 | 142 | print "" |
121 | 143 | print "OPTIONS:" |
| 144 | print " -force_lib -- assume all files are Sage library files," |
| 145 | print " regardless of location" |
122 | 146 | print " -long -- include lines with the phrase 'long time'" |
123 | | print " -verbose -- print debuging output during the test" |
| 147 | print " -verbose -- print debugging output during the test" |
124 | 148 | print " -optional -- also test all #optional examples" |
125 | 149 | print " -only-optional=list,of,tags -- only run doctests with " |
126 | 150 | print " #optional <nonempty subset of tags>" |
127 | 151 | print " if the list of tags is omitted, run all optional doctests" |
128 | 152 | print " -randorder -- if given, randomize *order* of tests" |
129 | 153 | print " -randorder=seed-- use seed to get same random order" |
| 154 | print " -sagenb -- test all sagenb files" |
130 | 155 | |
131 | 156 | sys.exit(1) |
132 | 157 | |
… |
… |
else: |
148 | 173 | print "\n\t" + "\n\t".join(failed) |
149 | 174 | |
150 | 175 | print "Total time for all tests: %.1f seconds"%(time.time() - t0) |
151 | | |
152 | | |
153 | | |