kopia lustrzana https://github.com/micropython/micropython-lib
unittest: Log failure tracebacks at test end.
Store traceback details for each test failure and log to console at the end of the test, like CPython version of the module does.pull/488/head
rodzic
a9cd99ce2d
commit
7d4d02edfc
|
@ -1,5 +1,13 @@
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
try:
|
||||||
|
import io
|
||||||
|
import traceback
|
||||||
|
except ImportError:
|
||||||
|
import uio as io
|
||||||
|
|
||||||
|
traceback = None
|
||||||
|
|
||||||
|
|
||||||
class SkipTest(Exception):
|
class SkipTest(Exception):
|
||||||
pass
|
pass
|
||||||
|
@ -160,7 +168,7 @@ class TestRunner:
|
||||||
def run(self, suite):
|
def run(self, suite):
|
||||||
res = TestResult()
|
res = TestResult()
|
||||||
for c in suite.tests:
|
for c in suite.tests:
|
||||||
run_class(c, res)
|
res.exceptions.extend(run_class(c, res))
|
||||||
|
|
||||||
print("Ran %d tests\n" % res.testsRun)
|
print("Ran %d tests\n" % res.testsRun)
|
||||||
if res.failuresNum > 0 or res.errorsNum > 0:
|
if res.failuresNum > 0 or res.errorsNum > 0:
|
||||||
|
@ -180,16 +188,27 @@ class TestResult:
|
||||||
self.failuresNum = 0
|
self.failuresNum = 0
|
||||||
self.skippedNum = 0
|
self.skippedNum = 0
|
||||||
self.testsRun = 0
|
self.testsRun = 0
|
||||||
|
self.exceptions = []
|
||||||
|
|
||||||
def wasSuccessful(self):
|
def wasSuccessful(self):
|
||||||
return self.errorsNum == 0 and self.failuresNum == 0
|
return self.errorsNum == 0 and self.failuresNum == 0
|
||||||
|
|
||||||
|
|
||||||
|
def capture_exc(e):
|
||||||
|
buf = io.StringIO()
|
||||||
|
if hasattr(sys, "print_exception"):
|
||||||
|
sys.print_exception(e, buf)
|
||||||
|
elif traceback is not None:
|
||||||
|
traceback.print_exception(None, e, sys.exc_info()[2], file=buf)
|
||||||
|
return buf.getvalue()
|
||||||
|
|
||||||
|
|
||||||
# TODO: Uncompliant
|
# TODO: Uncompliant
|
||||||
def run_class(c, test_result):
|
def run_class(c, test_result):
|
||||||
o = c()
|
o = c()
|
||||||
set_up = getattr(o, "setUp", lambda: None)
|
set_up = getattr(o, "setUp", lambda: None)
|
||||||
tear_down = getattr(o, "tearDown", lambda: None)
|
tear_down = getattr(o, "tearDown", lambda: None)
|
||||||
|
exceptions = []
|
||||||
for name in dir(o):
|
for name in dir(o):
|
||||||
if name.startswith("test"):
|
if name.startswith("test"):
|
||||||
print("%s (%s) ..." % (name, c.__qualname__), end="")
|
print("%s (%s) ..." % (name, c.__qualname__), end="")
|
||||||
|
@ -202,14 +221,14 @@ def run_class(c, test_result):
|
||||||
except SkipTest as e:
|
except SkipTest as e:
|
||||||
print(" skipped:", e.args[0])
|
print(" skipped:", e.args[0])
|
||||||
test_result.skippedNum += 1
|
test_result.skippedNum += 1
|
||||||
except:
|
except Exception as ex:
|
||||||
|
exceptions.append(capture_exc(ex))
|
||||||
print(" FAIL")
|
print(" FAIL")
|
||||||
test_result.failuresNum += 1
|
test_result.failuresNum += 1
|
||||||
# Uncomment to investigate failure in detail
|
|
||||||
# raise
|
|
||||||
continue
|
continue
|
||||||
finally:
|
finally:
|
||||||
tear_down()
|
tear_down()
|
||||||
|
return exceptions
|
||||||
|
|
||||||
|
|
||||||
def main(module="__main__"):
|
def main(module="__main__"):
|
||||||
|
@ -225,5 +244,9 @@ def main(module="__main__"):
|
||||||
suite.addTest(c)
|
suite.addTest(c)
|
||||||
runner = TestRunner()
|
runner = TestRunner()
|
||||||
result = runner.run(suite)
|
result = runner.run(suite)
|
||||||
|
if result.exceptions:
|
||||||
|
sep = "\n----------------------------------------------------------------------\n"
|
||||||
|
print(sep)
|
||||||
|
print(sep.join(result.exceptions))
|
||||||
# Terminate with non zero return code in case of failures
|
# Terminate with non zero return code in case of failures
|
||||||
sys.exit(result.failuresNum > 0)
|
sys.exit(result.failuresNum > 0)
|
||||||
|
|
Ładowanie…
Reference in New Issue