colortest¶
ontopy.colortest
¶
Print tests in colors.
Adapted from https://github.com/meshy/colour-runner by Charlie Denton License: MIT
ColourTextTestResult (TestResult)
¶
A test result class that prints colour formatted text results to a stream.
Based on https://github.com/python/cpython/blob/3.3/Lib/unittest/runner.py
Source code in ontopy/colortest.py
class ColourTextTestResult(TestResult):
"""
A test result class that prints colour formatted text results to a stream.
Based on https://github.com/python/cpython/blob/3.3/Lib/unittest/runner.py
"""
formatter = formatters.Terminal256Formatter() # pylint: disable=no-member
lexer = Lexer()
separator1 = "=" * 70
separator2 = "-" * 70
indent = " " * 4
# if `checkmode` is true, simplified output will be generated with
# no traceback
checkmode = False
_terminal = Terminal()
colours = {
None: str,
"error": _terminal.bold_red,
"expected": _terminal.blue,
# "fail": _terminal.bold_yellow,
"fail": _terminal.bold_magenta,
"skip": str,
"success": _terminal.green,
"title": _terminal.blue,
"unexpected": _terminal.bold_red,
}
_test_class = None
def __init__(self, stream, descriptions, verbosity):
super().__init__(stream, descriptions, verbosity)
self.stream = stream
self.show_all = verbosity > 1
self.dots = verbosity == 1
self.descriptions = descriptions
def getShortDescription(self, test):
doc_first_line = test.shortDescription()
if self.descriptions and doc_first_line:
return self.indent + doc_first_line
return self.indent + test._testMethodName
def getLongDescription(self, test):
doc_first_line = test.shortDescription()
if self.descriptions and doc_first_line:
return "\n".join((str(test), doc_first_line))
return str(test)
def getClassDescription(self, test):
test_class = test.__class__
doc = test_class.__doc__
if self.descriptions and doc:
return doc.split("\n")[0].strip()
return strclass(test_class)
def startTest(self, test):
super().startTest(test)
pos = 0
if self.show_all:
if self._test_class != test.__class__:
self._test_class = test.__class__
title = self.getClassDescription(test)
self.stream.writeln(self.colours["title"](title))
descr = self.getShortDescription(test)
self.stream.write(descr)
pos += len(descr)
self.stream.write(" " * (70 - pos))
# self.stream.write(' ' * (self._terminal.width - 10 - pos))
# self.stream.write(' ... ')
self.stream.flush()
def printResult(self, short, extended, colour_key=None):
colour = self.colours[colour_key]
if self.show_all:
self.stream.writeln(colour(extended))
elif self.dots:
self.stream.write(colour(short))
self.stream.flush()
def addSuccess(self, test):
super().addSuccess(test)
self.printResult(".", "ok", "success")
def addError(self, test, err):
super().addError(test, err)
self.printResult("E", "ERROR", "error")
def addFailure(self, test, err):
super().addFailure(test, err)
self.printResult("F", "FAIL", "fail")
def addSkip(self, test, reason):
super().addSkip(test, reason)
if self.checkmode:
self.printResult("s", "skipped", "skip")
else:
self.printResult("s", f"skipped {reason!r}", "skip")
def addExpectedFailure(self, test, err):
super().addExpectedFailure(test, err)
self.printResult("x", "expected failure", "expected")
def addUnexpectedSuccess(self, test):
super().addUnexpectedSuccess(test)
self.printResult("u", "unexpected success", "unexpected")
def printErrors(self):
if self.dots or self.show_all:
self.stream.writeln()
self.printErrorList("ERROR", self.errors)
self.printErrorList("FAIL", self.failures)
def printErrorList(self, flavour, errors):
colour = self.colours[flavour.lower()]
for test, err in errors:
if self.checkmode and flavour == "FAIL":
self.stream.writeln(self.separator1)
title = f"{flavour}: {test.shortDescription()}"
self.stream.writeln(colour(title))
self.stream.writeln(str(test))
if self.show_all:
self.stream.writeln(self.separator2)
lines = str(err).split("\n")
i = 1
for line in lines[1:]:
if line.startswith(" "):
i += 1
else:
break
self.stream.writeln(
highlight(
"\n".join(lines[i:]), self.lexer, self.formatter
)
)
else:
self.stream.writeln(self.separator1)
title = f"{flavour}: {self.getLongDescription(test)}"
self.stream.writeln(colour(title))
self.stream.writeln(self.separator2)
self.stream.writeln(highlight(err, self.lexer, self.formatter))
addError(self, test, err)
¶
Called when an error has occurred. 'err' is a tuple of values as returned by sys.exc_info().
Source code in ontopy/colortest.py
def addError(self, test, err):
super().addError(test, err)
self.printResult("E", "ERROR", "error")
addExpectedFailure(self, test, err)
¶
Called when an expected failure/error occurred.
Source code in ontopy/colortest.py
def addExpectedFailure(self, test, err):
super().addExpectedFailure(test, err)
self.printResult("x", "expected failure", "expected")
addFailure(self, test, err)
¶
Called when an error has occurred. 'err' is a tuple of values as returned by sys.exc_info().
Source code in ontopy/colortest.py
def addFailure(self, test, err):
super().addFailure(test, err)
self.printResult("F", "FAIL", "fail")
addSkip(self, test, reason)
¶
Called when a test is skipped.
Source code in ontopy/colortest.py
def addSkip(self, test, reason):
super().addSkip(test, reason)
if self.checkmode:
self.printResult("s", "skipped", "skip")
else:
self.printResult("s", f"skipped {reason!r}", "skip")
addSuccess(self, test)
¶
Called when a test has completed successfully
Source code in ontopy/colortest.py
def addSuccess(self, test):
super().addSuccess(test)
self.printResult(".", "ok", "success")
addUnexpectedSuccess(self, test)
¶
Called when a test was expected to fail, but succeed.
Source code in ontopy/colortest.py
def addUnexpectedSuccess(self, test):
super().addUnexpectedSuccess(test)
self.printResult("u", "unexpected success", "unexpected")
printErrors(self)
¶
Called by TestRunner after test run
Source code in ontopy/colortest.py
def printErrors(self):
if self.dots or self.show_all:
self.stream.writeln()
self.printErrorList("ERROR", self.errors)
self.printErrorList("FAIL", self.failures)
startTest(self, test)
¶
Called when the given test is about to be run
Source code in ontopy/colortest.py
def startTest(self, test):
super().startTest(test)
pos = 0
if self.show_all:
if self._test_class != test.__class__:
self._test_class = test.__class__
title = self.getClassDescription(test)
self.stream.writeln(self.colours["title"](title))
descr = self.getShortDescription(test)
self.stream.write(descr)
pos += len(descr)
self.stream.write(" " * (70 - pos))
# self.stream.write(' ' * (self._terminal.width - 10 - pos))
# self.stream.write(' ... ')
self.stream.flush()
ColourTextTestRunner (TextTestRunner)
¶
A test runner that uses colour in its output.
Source code in ontopy/colortest.py
class ColourTextTestRunner(
TextTestRunner
): # pylint: disable=too-few-public-methods
"""A test runner that uses colour in its output."""
resultclass = ColourTextTestResult
resultclass (TestResult)
¶
A test result class that prints colour formatted text results to a stream.
Based on https://github.com/python/cpython/blob/3.3/Lib/unittest/runner.py
Source code in ontopy/colortest.py
class ColourTextTestResult(TestResult):
"""
A test result class that prints colour formatted text results to a stream.
Based on https://github.com/python/cpython/blob/3.3/Lib/unittest/runner.py
"""
formatter = formatters.Terminal256Formatter() # pylint: disable=no-member
lexer = Lexer()
separator1 = "=" * 70
separator2 = "-" * 70
indent = " " * 4
# if `checkmode` is true, simplified output will be generated with
# no traceback
checkmode = False
_terminal = Terminal()
colours = {
None: str,
"error": _terminal.bold_red,
"expected": _terminal.blue,
# "fail": _terminal.bold_yellow,
"fail": _terminal.bold_magenta,
"skip": str,
"success": _terminal.green,
"title": _terminal.blue,
"unexpected": _terminal.bold_red,
}
_test_class = None
def __init__(self, stream, descriptions, verbosity):
super().__init__(stream, descriptions, verbosity)
self.stream = stream
self.show_all = verbosity > 1
self.dots = verbosity == 1
self.descriptions = descriptions
def getShortDescription(self, test):
doc_first_line = test.shortDescription()
if self.descriptions and doc_first_line:
return self.indent + doc_first_line
return self.indent + test._testMethodName
def getLongDescription(self, test):
doc_first_line = test.shortDescription()
if self.descriptions and doc_first_line:
return "\n".join((str(test), doc_first_line))
return str(test)
def getClassDescription(self, test):
test_class = test.__class__
doc = test_class.__doc__
if self.descriptions and doc:
return doc.split("\n")[0].strip()
return strclass(test_class)
def startTest(self, test):
super().startTest(test)
pos = 0
if self.show_all:
if self._test_class != test.__class__:
self._test_class = test.__class__
title = self.getClassDescription(test)
self.stream.writeln(self.colours["title"](title))
descr = self.getShortDescription(test)
self.stream.write(descr)
pos += len(descr)
self.stream.write(" " * (70 - pos))
# self.stream.write(' ' * (self._terminal.width - 10 - pos))
# self.stream.write(' ... ')
self.stream.flush()
def printResult(self, short, extended, colour_key=None):
colour = self.colours[colour_key]
if self.show_all:
self.stream.writeln(colour(extended))
elif self.dots:
self.stream.write(colour(short))
self.stream.flush()
def addSuccess(self, test):
super().addSuccess(test)
self.printResult(".", "ok", "success")
def addError(self, test, err):
super().addError(test, err)
self.printResult("E", "ERROR", "error")
def addFailure(self, test, err):
super().addFailure(test, err)
self.printResult("F", "FAIL", "fail")
def addSkip(self, test, reason):
super().addSkip(test, reason)
if self.checkmode:
self.printResult("s", "skipped", "skip")
else:
self.printResult("s", f"skipped {reason!r}", "skip")
def addExpectedFailure(self, test, err):
super().addExpectedFailure(test, err)
self.printResult("x", "expected failure", "expected")
def addUnexpectedSuccess(self, test):
super().addUnexpectedSuccess(test)
self.printResult("u", "unexpected success", "unexpected")
def printErrors(self):
if self.dots or self.show_all:
self.stream.writeln()
self.printErrorList("ERROR", self.errors)
self.printErrorList("FAIL", self.failures)
def printErrorList(self, flavour, errors):
colour = self.colours[flavour.lower()]
for test, err in errors:
if self.checkmode and flavour == "FAIL":
self.stream.writeln(self.separator1)
title = f"{flavour}: {test.shortDescription()}"
self.stream.writeln(colour(title))
self.stream.writeln(str(test))
if self.show_all:
self.stream.writeln(self.separator2)
lines = str(err).split("\n")
i = 1
for line in lines[1:]:
if line.startswith(" "):
i += 1
else:
break
self.stream.writeln(
highlight(
"\n".join(lines[i:]), self.lexer, self.formatter
)
)
else:
self.stream.writeln(self.separator1)
title = f"{flavour}: {self.getLongDescription(test)}"
self.stream.writeln(colour(title))
self.stream.writeln(self.separator2)
self.stream.writeln(highlight(err, self.lexer, self.formatter))
addError(self, test, err)
¶
Called when an error has occurred. 'err' is a tuple of values as returned by sys.exc_info().
Source code in ontopy/colortest.py
def addError(self, test, err):
super().addError(test, err)
self.printResult("E", "ERROR", "error")
addExpectedFailure(self, test, err)
¶
Called when an expected failure/error occurred.
Source code in ontopy/colortest.py
def addExpectedFailure(self, test, err):
super().addExpectedFailure(test, err)
self.printResult("x", "expected failure", "expected")
addFailure(self, test, err)
¶
Called when an error has occurred. 'err' is a tuple of values as returned by sys.exc_info().
Source code in ontopy/colortest.py
def addFailure(self, test, err):
super().addFailure(test, err)
self.printResult("F", "FAIL", "fail")
addSkip(self, test, reason)
¶
Called when a test is skipped.
Source code in ontopy/colortest.py
def addSkip(self, test, reason):
super().addSkip(test, reason)
if self.checkmode:
self.printResult("s", "skipped", "skip")
else:
self.printResult("s", f"skipped {reason!r}", "skip")
addSuccess(self, test)
¶
Called when a test has completed successfully
Source code in ontopy/colortest.py
def addSuccess(self, test):
super().addSuccess(test)
self.printResult(".", "ok", "success")
addUnexpectedSuccess(self, test)
¶
Called when a test was expected to fail, but succeed.
Source code in ontopy/colortest.py
def addUnexpectedSuccess(self, test):
super().addUnexpectedSuccess(test)
self.printResult("u", "unexpected success", "unexpected")
printErrors(self)
¶
Called by TestRunner after test run
Source code in ontopy/colortest.py
def printErrors(self):
if self.dots or self.show_all:
self.stream.writeln()
self.printErrorList("ERROR", self.errors)
self.printErrorList("FAIL", self.failures)
startTest(self, test)
¶
Called when the given test is about to be run
Source code in ontopy/colortest.py
def startTest(self, test):
super().startTest(test)
pos = 0
if self.show_all:
if self._test_class != test.__class__:
self._test_class = test.__class__
title = self.getClassDescription(test)
self.stream.writeln(self.colours["title"](title))
descr = self.getShortDescription(test)
self.stream.write(descr)
pos += len(descr)
self.stream.write(" " * (70 - pos))
# self.stream.write(' ' * (self._terminal.width - 10 - pos))
# self.stream.write(' ... ')
self.stream.flush()