#!/usr/bin/env python # Copyright (c) 2009 Tim Freeman # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. # # (This is the standard MIT License, copied from # http://www.opensource.org/licenses/mit-license.php on 24 Apr 2007.) #desc The top level of the test harness. Useful if you want to #desc run many tests or run with coverage analysis. import sys import os import os.path import glob import time def safe_system(cmd): status = os.system(cmd) if status != 0: raise Exception("Failed to run %r" % cmd,) nocover = ["regress.py", "coverage.py", "test_util.py", "index_html.py"] def do_coverage(testfiles, to_cover, cover): start = time.time() coverage_file = ".coverage" if os.path.exists(coverage_file): os.remove(coverage_file) failures = 0 for testfile in testfiles: sys.stdout.write("Running %r..." % (testfile,)) sys.stdout.flush() command = "python " if cover: command += "coverage.py -x " status = os.system(command + testfile) if status == 0: print("Done.") else: failures += 1 if failures: raise Exception("Some tests failed to run.") to_cover = " ".join(to_cover) if cover: safe_system("python coverage.py -a " + to_cover) safe_system("python coverage.py -r " + to_cover) print "%6.1f seconds elapsed" % (time.time() - start) def usage(): sys.stderr.write("""Usage: regress.py [-nocover] [files] [-skip files] Run unit tests and optionally does coverage analysis for the given files. This assumes that the test file for foo.py is foo_test.py. Specify the foo.py's as the argument. Any files matching *_test.py will be ignored, and any files appearing after "-skip" will be ignored. You can leave out the .py extension. """) sys.exit(1) def trim_ext(ext, f): if f.endswith(ext): return f[:len(f)-len(ext)] else: return f def trim_file(f): f = trim_ext(".py", f) f = trim_ext("_test", f) return f coverage = True if len(sys.argv) >= 2 and sys.argv[1] == "-nocover": coverage = False sys.argv = [sys.argv[0]] + sys.argv[2:] skip = "-skip" if skip in sys.argv: where = sys.argv.index(skip) nocover += sys.argv[where + 1:] sys.argv = sys.argv[:where] if len(sys.argv) == 1: testfiles = glob.glob("*_test.py") to_cover = [f for f in glob.glob("*.py") if f not in nocover + testfiles] do_coverage(testfiles, to_cover, coverage) else: to_cover = [trim_file(f)+".py" for f in sys.argv[1:] if not trim_file(f).endswith("_test") and not trim_file(f)+".py" in nocover] testfiles = [trim_file(f)+"_test.py" for f in to_cover] for f in to_cover: if not os.path.exists(f): sys.stderr.write("Can't find a file named %r\n" % (f,)) usage() do_coverage(testfiles, to_cover, coverage)