#!/usr/bin/env python # # This is a TAP compiler for python unittest # # It hooks into python's standard unittest module, and produces TAP output. # # This produces the Test Anything Protocol (ie: TAP) # https://metacpan.org/pod/release/PETDANCE/Test-Harness-2.64/lib/Test/Harness/TAP.pod # # Based on code from here: # https://github.com/vit1251/unittest-tap-reporting # import argparse import imp import os import sys import time import traceback import unittest def write_line(format, *args): sys.stdout.write(format % args) sys.stdout.write("\n") sys.stdout.flush() class TAPTestResult(unittest.result.TestResult): def __init__(self): unittest.result.TestResult.__init__(self) self.number = 0 def addSuccess(self, test): self.number += 1 write_line("ok %d %s", self.number, test.id()) def addSkip(self, test, reason): self.number += 1 write_line("not ok %d # skip %s", self.number, test.id()) write_line("# %s", reason) def addError(self, test, exc): (etype, evalue, etraceback) = exc traceback.print_exception(etype, evalue, etraceback, file=sys.stderr) self.number += 1 write_line("not ok %d %s", self.number, test.id()) def addFailure(self, test, err): (etype, evalue, etraceback) = exc traceback.print_exception(etype, evalue, etraceback, limit=1, file=sys.stderr) self.number += 1 write_line("not ok %d %s", self.number, test.id()) class TAPTestRunner(object): def __init__(self): pass def run(self, test): write_line("1..%d", test.countTestCases()) result = TAPTestResult() startTestRun = getattr(result, 'startTestRun', lambda : None) startTestRun() try: test(result) finally: stopTestRun = getattr(result, 'stopTestRun', lambda : None) stopTestRun() return result def main(argv): parser = argparse.ArgumentParser(description='Python unittest TAP driver') parser.add_argument('module', nargs=1, help="A unittest test module to run") args = parser.parse_args(argv[1:]) (name, ext) = os.path.splitext(os.path.basename(args.module[0])) module = imp.load_source(name, args.module[0]) loader = unittest.TestLoader() tests = loader.loadTestsFromModule(module) runner = TAPTestRunner() runner.run(tests) if __name__ == "__main__": sys.exit(main(sys.argv))