def get_uncovered_lines(self, uncovered_lines, max_num=3): '''Searches for untested lines of code. Returns a string listing the line numbers. If the number of uncovered lines is greater than `max_num`, this will only explicitly list the first `max_num` uncovered lines, followed by ' and ## more' (where '##' is the total number of additional uncovered lines. ''' if len(uncovered_lines) > max_num: template_str = [] for i in range(max_num): line_num = uncovered_lines[i] template_str.append(line_num) if i is not (max_num - 1): template_str.append(', ') template_str.append( ', and {num_more_uncovered:d} more'.format( num_more_uncovered=len(uncovered_lines) - max_num )) return yellow(''.join(template_str)) return yellow(', '.join(uncovered_lines))
def print_profile(self, threshold): '''Prints the 10 slowest topics that took longer than `threshold` to test. ''' '''Prints the 10 slowest topics that took longer than `threshold` to test. ''' MAX_PATH_SIZE = 40 topics = self.result.get_worst_topics(number=10, threshold=threshold) if topics: print(self.header('Slowest Topics')) table_header = yellow(' {0}'.format(dim('#'))) table_header += yellow( ' Elapsed Context File Path ') table_header += yellow(' Context Name') print(table_header) for index, topic in enumerate(topics): name = self.under_split(topic['context']) name = self.camel_split(name) topic['path'] = os.path.realpath(topic['path']) topic['path'] = '{0!s}'.format(topic['path']) topic['path'] = os.path.relpath(topic['path'], os.path.abspath(os.curdir)) data = { 'number': '{number:#2}'.format(number=index + 1), 'time': '{time:.05f}s'.format(time=topic['elapsed']), 'path': '{path:<{width}}'.format( path=topic['path'][-MAX_PATH_SIZE:], width=MAX_PATH_SIZE), 'name': '{name}'.format(name=name), } for k, v in data.items(): if k == 'number': colorized = blue if k == 'time': colorized = green if k == 'path': colorized = lambda x: dim(white(x)) if k == 'name': colorized = green data[k] = colorized(v) print(' {number} {time}{0}{path}{0}{name}'.format( 4 * ' ', **data)) print()
def print_profile(self, threshold): '''Prints the 10 slowest topics that took longer than `threshold` to test. ''' '''Prints the 10 slowest topics that took longer than `threshold` to test. ''' MAX_PATH_SIZE = 40 topics = self.result.get_worst_topics(number=10, threshold=threshold) if topics: print(self.header('Slowest Topics')) table_header = yellow(' {0}'.format(dim('#'))) table_header += yellow(' Elapsed Context File Path ') table_header += yellow(' Context Name') print(table_header) for index, topic in enumerate(topics): name = self.under_split(topic['context']) name = self.camel_split(name) topic['path'] = os.path.realpath(topic['path']) topic['path'] = '{0!s}'.format(topic['path']) topic['path'] = os.path.relpath(topic['path'], os.path.abspath(os.curdir)) data = { 'number': '{number:#2}'.format(number=index + 1), 'time': '{time:.05f}s'.format(time=topic['elapsed']), 'path': '{path:<{width}}'.format( path=topic['path'][-MAX_PATH_SIZE:], width=MAX_PATH_SIZE), 'name': '{name}'.format(name=name), } for k, v in data.items(): if k == 'number': colorized = blue if k == 'time': colorized = green if k == 'path': colorized = lambda x: dim(white(x)) if k == 'name': colorized = green data[k] = colorized(v) print( ' {number} {time}{0}{path}{0}{name}'.format( 4 * ' ', **data) ) print()
def _print_failed_context(): ctx = test['context_instance'] def _print_traceback(): self.indent += 2 ### NOTE: ### Commented out try/except; potential debugging hinderance #try: traceback_args = None if (hasattr(test, 'topic') and hasattr(test['topic'], 'error') and test['topic']['error'] is not None): print '\n' + self.indent_msg(blue('Topic Error:')) traceback_args = tuple(*test['topic'].error) else: traceback_args = (test['error']['type'], test['error']['value'], test['error']['traceback']) self.print_traceback(*traceback_args) # except Exception: # # should never occur! # err_msg = '''Unexpected error in PyVows! # PyVows error occurred in: ({0!s}) # Context was: {1!r} # # ''' # # from os.path import abspath # raise VowsInternalError(err_msg, 'pyvows.reporting.test', ctx) # print file and line number if 'file' in test: file_msg = 'found in {test[file]} at line {test[lineno]}'.format(test=test) print print self.indent_msg(red(file_msg)) print self.indent -= 2 self.humanized_print('{0} {test}'.format( VowsReporter.BROKEN, test=test['name'])) # print generated topic (if applicable) if ctx.generated_topic: value = yellow(test['topic']) self.humanized_print('') self.humanized_print('\tTopic value:') self.humanized_print('\t{value}'.format(value=value)) self.humanized_print('\n' * 2) # print traceback _print_traceback()
def _print_failed_context(): ctx = test['context_instance'] def _print_traceback(): self.indent += 2 ### NOTE: ### Commented out try/except; potential debugging hinderance #try: traceback_args = None if (hasattr(test, 'topic') and hasattr(test['topic'], 'error') and test['topic']['error'] is not None): print '\n' + self.indent_msg(blue('Topic Error:')) traceback_args = tuple(*test['topic'].error) else: traceback_args = (test['error']['type'], test['error']['value'], test['error']['traceback']) self.print_traceback(*traceback_args) # except Exception: # # should never occur! # err_msg = '''Unexpected error in PyVows! # PyVows error occurred in: ({0!s}) # Context was: {1!r} # # ''' # # from os.path import abspath # raise VowsInternalError(err_msg, 'pyvows.reporting.test', ctx) # print file and line number if 'file' in test: file_msg = 'found in {test[file]} at line {test[lineno]}'.format( test=test) print print self.indent_msg(red(file_msg)) print self.indent -= 2 self.humanized_print('{0} {test}'.format(VowsReporter.BROKEN, test=test['name'])) # print generated topic (if applicable) if ctx.generated_topic: value = yellow(test['topic']) self.humanized_print('') self.humanized_print('\tTopic value:') self.humanized_print('\t{value}'.format(value=value)) self.humanized_print('\n' * 2) # print traceback _print_traceback()
def print_traceback(self, err_type, err_obj, err_traceback): '''Prints a color-formatted traceback with appropriate indentation.''' if isinstance(err_obj, AssertionError): error_msg = err_obj else: error_msg = unicode(err_obj) print(self.indent_msg(red(error_msg))) if self.verbosity >= V_NORMAL: traceback_msg = traceback.format_exception(err_type, err_obj, err_traceback) traceback_msg = self.format_traceback(traceback_msg) traceback_msg = '\n{traceback}'.format(traceback=traceback_msg) traceback_msg = self.indent_msg(yellow(traceback_msg)) print(traceback_msg)
def get_uncovered_lines(self, uncovered_lines, max_num=3): '''Searches for untested lines of code. Returns a string listing the line numbers. If the number of uncovered lines is greater than `max_num`, this will only explicitly list the first `max_num` uncovered lines, followed by ' and ## more' (where '##' is the total number of additional uncovered lines. ''' if len(uncovered_lines) > max_num: template_str = [] for i in range(max_num): line_num = uncovered_lines[i] template_str.append(line_num) if i is not (max_num - 1): template_str.append(', ') template_str.append(', and {num_more_uncovered:d} more'.format( num_more_uncovered=len(uncovered_lines) - max_num)) return yellow(''.join(template_str)) return yellow(', '.join(uncovered_lines))
def print_traceback(self, err_type, err_obj, err_traceback): '''Prints a color-formatted traceback with appropriate indentation.''' if isinstance(err_obj, AssertionError): error_msg = err_obj else: error_msg = unicode(err_obj) print self.indent_msg(red(error_msg)) if self.verbosity >= V_NORMAL: traceback_msg = traceback.format_exception(err_type, err_obj, err_traceback) traceback_msg = self.format_traceback(traceback_msg) traceback_msg = '\n{traceback}'.format(traceback=traceback_msg) traceback_msg = self.indent_msg(yellow(traceback_msg)) print traceback_msg
def print_traceback(self, err_type, err_obj, err_traceback, file=sys.stdout): '''Prints a color-formatted traceback with appropriate indentation.''' if isinstance(err_obj, AssertionError): error_msg = err_obj elif isinstance(err_obj, bytes): error_msg = err_obj.decode('utf8') else: error_msg = err_obj print(self.indent_msg(red(error_msg)), file=file) if self.verbosity >= V_NORMAL: traceback_msg = traceback.format_exception(err_type, err_obj, err_traceback) traceback_msg = self.format_traceback(traceback_msg) traceback_msg = '\n{traceback}'.format(traceback=traceback_msg) traceback_msg = self.indent_msg(yellow(traceback_msg)) print(traceback_msg, file=file)
def main(): '''PyVows' runtime implementation. ''' # needs to be imported here, else the no-color option won't work from pyvows.reporting import VowsDefaultReporter arguments = Parser().parse_args() if arguments.template: from pyvows.utils import template template() sys.exit() # Exit after printing template, since it's # supposed to be redirected from STDOUT by the user path, pattern = arguments.path, arguments.pattern if path and isfile(path): path, pattern = split(path) if not path: path = os.curdir if arguments.no_color: for color_name, value in inspect.getmembers(Fore): if not color_name.startswith('_'): setattr(Fore, color_name, '') if arguments.cover and COVERAGE_AVAILABLE: cov = coverage(source=arguments.cover_package, omit=arguments.cover_omit) cov.erase() cov.start() prune = arguments.exclude verbosity = len(arguments.verbosity) if arguments.verbosity else 2 result = run(path, pattern, verbosity, arguments.progress, prune) reporter = VowsDefaultReporter(result, verbosity) # Print test results first reporter.pretty_print() # Print profile if necessary if arguments.profile: reporter.print_profile(arguments.profile_threshold) # Print coverage if necessary if result.successful and arguments.cover: # if coverage was requested, but unavailable, warn the user if not COVERAGE_AVAILABLE: print() print(yellow('WARNING: Cover disabled because coverage could not be found.')) print(yellow('Make sure it is installed and accessible.')) print() # otherwise, we're good else: cov.stop() xml = '' try: with tempfile.NamedTemporaryFile() as tmp: cov.xml_report(outfile=tmp.name) tmp.seek(0) xml = tmp.read() except Exception: err = sys.exc_info()[1] print("Could not run coverage. Error: %s" % err) if xml: if arguments.cover_report: with open(arguments.cover_report, 'w') as report: report.write(xml) arguments.cover_threshold /= 100.0 reporter.print_coverage(xml, arguments.cover_threshold) # Write XUnit if necessary if arguments.xunit_output: xunit = XUnitReporter(result) xunit.write_report(arguments.xunit_file) sys.exit(result.errored_tests)
def main(): '''PyVows' runtime implementation. ''' # needs to be imported here, else the no-color option won't work from pyvows.reporting import VowsDefaultReporter arguments = Parser().parse_args() if arguments.template: from pyvows.utils import template template() sys.exit() # Exit after printing template, since it's # supposed to be redirected from STDOUT by the user path, pattern = arguments.path, arguments.pattern if path and isfile(path): path, pattern = split(path) if not path: path = os.curdir if arguments.no_color: for color_name, value in inspect.getmembers(Fore): if not color_name.startswith('_'): setattr(Fore, color_name, '') if arguments.cover and COVERAGE_AVAILABLE: cov = coverage(source=arguments.cover_package, omit=arguments.cover_omit) cov.erase() cov.start() verbosity = len(arguments.verbosity) if arguments.verbosity else 2 result = run(path, pattern, verbosity, arguments.progress, exclusion_patterns=arguments.exclude, inclusion_patterns=arguments.include, capture_output=arguments.capture_output) reporter = VowsDefaultReporter(result, verbosity) # Print test results first reporter.pretty_print() # Print profile if necessary if arguments.profile: reporter.print_profile(arguments.profile_threshold) # Print coverage if necessary if result.successful and arguments.cover: # if coverage was requested, but unavailable, warn the user if not COVERAGE_AVAILABLE: print() print( yellow( 'WARNING: Cover disabled because coverage could not be found.' )) print(yellow('Make sure it is installed and accessible.')) print() # otherwise, we're good else: cov.stop() xml = '' try: with tempfile.NamedTemporaryFile() as tmp: cov.xml_report(outfile=tmp.name) tmp.seek(0) xml = tmp.read() except Exception: err = sys.exc_info()[1] print("Could not run coverage. Error: %s" % err) if xml: if arguments.cover_report: with open(arguments.cover_report, 'wb') as report: report.write(xml) arguments.cover_threshold /= 100.0 reporter.print_coverage(xml, arguments.cover_threshold) # Write XUnit if necessary if arguments.xunit_output: xunit = XUnitReporter(result) xunit.write_report(arguments.xunit_file) sys.exit(result.errored_tests)