def write_report(name, project, logger, result, console_out): project.write_report("%s" % name, console_out) report = {"tests-run": result.testsRun, "errors": [], "failures": []} for error in result.errors: report["errors"].append({"test": error[0].id(), "traceback": error[1]}) logger.error("Test has error: %s", error[0].id()) if project.get_property("verbose"): print_text_line(error[1]) for failure in result.failures: report["failures"].append({"test": failure[0].id(), "traceback": failure[1]}) logger.error("Test failed: %s", failure[0].id()) if project.get_property("verbose"): print_text_line(failure[1]) project.write_report("%s.json" % name, render_report(report)) report_to_ci_server(project, result)
def write_report_and_ensure_all_tests_passed(self): self.project.write_report("integrationtest.json", render_report(self.test_report)) self.logger.info("Executed %d integration tests.", self.tests_executed) if self.tests_failed: raise BuildFailedException( "%d of %d integration tests failed." % (self.tests_failed, self.tests_executed))
def test_should_render_report(self): report = {"eggs": ["foo", "bar"], "spam": "baz"} actual_report_as_json_string = render_report(report) actual_report = loads(actual_report_as_json_string) actual_keys = sorted(actual_report.keys()) self.assertEquals(actual_keys, ['eggs', 'spam']) self.assertEquals(actual_report['eggs'], ["foo", "bar"]) self.assertEquals(actual_report['spam'], "baz")
def write_report(project, test_results): report = {"tests-run": test_results.number_of_tests_executed, "time_in_millis": test_results.execution_time, "failures": []} for test_result in test_results.test_results: if test_result.success: continue report["failures"].append({"test": test_result.test_definition.name, "message": test_result.message, "traceback": test_result.traceback_as_string}) project.write_report("pyfix_unittest.json", render_report(report))
def test_should_render_report(self): report = {"eggs": ["foo", "bar"], "spam": "baz"} actual_report_as_json_string = render_report(report) actual_report = loads(actual_report_as_json_string) actual_keys = sorted(actual_report.keys()) self.assertEquals(actual_keys, ["eggs", "spam"]) self.assertEquals(actual_report["eggs"], ["foo", "bar"]) self.assertEquals(actual_report["spam"], "baz")
def execute_pychecker(project, logger): command_line = build_command_line(project) logger.info("Executing pychecker on project sources: %s" % (' '.join(command_line))) _, report_file = execute_tool_on_modules(project, "pychecker", command_line, True) warnings = read_file(report_file) report = parse_pychecker_output(project, warnings) project.write_report("pychecker.json", render_report(report.to_json_dict())) if len(warnings) != 0: logger.warn("Found %d warning%s produced by pychecker. See %s for details.", len(warnings), "s" if len(warnings) != 1 else "", report_file) threshold = project.get_property("pychecker_break_build_threshold") if project.get_property("pychecker_break_build") and len(warnings) > threshold: raise BuildFailedException("Found warnings produced by pychecker")
def execute_pychecker(project, logger): command_line = build_command_line(project) logger.info("Executing pychecker on project sources: %s" % (' '.join(command_line))) _, report_file = execute_tool_on_modules(project, "pychecker", command_line, True) warnings = read_file(report_file) report = parse_pychecker_output(project, warnings) project.write_report("pychecker.json", render_report(report.to_json_dict())) if len(warnings) != 0: logger.warn( "Found %d warning%s produced by pychecker. See %s for details.", len(warnings), "s" if len(warnings) != 1 else "", report_file) threshold = project.get_property("pychecker_break_build_threshold") if project.get_property( "pychecker_break_build") and len(warnings) > threshold: raise BuildFailedException("Found warnings produced by pychecker")
def do_coverage(project, logger, reactor, execution_prefix, execution_name, target_task, shortest_plan): """ This function MUST ALWAYS execute in a fork. The sys.modules will be manipulated extensively to stage the tests properly, which may affect execute down the line. It's best to simple let this method exit and the fork die rather than to try to recover. """ source_tree_path = project.get_property("dir_source_main_python") module_names = _discover_modules_to_cover(project) for module_name in module_names: logger.debug("Module '%s' coverage to be verified", module_name) _delete_non_essential_modules() __import__("pybuilder.plugins.python") # Reimport self # Starting fresh from coverage import coverage as coverage_factory coverage = coverage_factory(cover_pylib=False, branch=True, source=[source_tree_path]) try: project.set_property( '__running_coverage', True ) # tell other plugins that we are not really unit testing right now _start_coverage(coverage) if shortest_plan: reactor.execute_task_shortest_plan(target_task) else: reactor.execute_task(target_task) finally: _stop_coverage(coverage) project.set_property('__running_coverage', False) coverage_too_low = False threshold = project.get_property("%s_threshold_warn" % execution_prefix) exceptions = project.get_property("%s_exceptions" % execution_prefix) report = {"module_names": []} sum_lines = 0 sum_lines_not_covered = 0 modules = [] for module_name in module_names: try: module = sys.modules[module_name] except KeyError: logger.warn("Module '%s' was not imported by the covered tests", module_name) try: module = __import__(module_name) except SyntaxError as e: logger.warn( "Coverage for module '%s' cannot be established - syntax error: %s", module_name, e) continue if module not in modules: modules.append(module) module_report_data = build_module_report(coverage, module) should_ignore_module = module_name in exceptions if not should_ignore_module: sum_lines += module_report_data[0] sum_lines_not_covered += module_report_data[2] module_report = { "module": module_name, "coverage": module_report_data[4], "sum_lines": module_report_data[0], "lines": module_report_data[1], "sum_lines_not_covered": module_report_data[2], "lines_not_covered": module_report_data[3], } logger.debug("Module coverage report: %s", module_report) report["module_names"].append(module_report) if module_report_data[4] < threshold: msg = "Test coverage below %2d%% for %s: %2d%%" % ( threshold, module_name, module_report_data[4]) if not should_ignore_module: logger.warn(msg) coverage_too_low = True else: logger.info(msg) if sum_lines == 0: overall_coverage = 0 else: overall_coverage = (sum_lines - sum_lines_not_covered) * 100 / sum_lines report["overall_coverage"] = overall_coverage if overall_coverage < threshold: logger.warn("Overall %s is below %2d%%: %2d%%", execution_name, threshold, overall_coverage) coverage_too_low = True else: logger.info("Overall %s is %2d%%", execution_name, overall_coverage) project.write_report("%s.json" % execution_prefix, render_report(report)) _write_summary_report(coverage, project, modules, execution_prefix, execution_name) if coverage_too_low and project.get_property( "%s_break_build" % execution_prefix): raise BuildFailedException( "Test coverage for at least one module is below %d%%", threshold)
def _build_coverage_report(project, logger, execution_name, execution_prefix, coverage, modules): coverage_too_low = False branch_coverage_too_low = False branch_partial_coverage_too_low = False threshold = project.get_property("%s_threshold_warn" % execution_prefix) branch_threshold = project.get_property("%s_branch_threshold_warn" % execution_prefix) branch_partial_threshold = project.get_property( "%s_branch_partial_threshold_warn" % execution_prefix) report = {"module_names": []} sum_lines = 0 sum_lines_not_covered = 0 sum_branches = 0 sum_branches_missing = 0 sum_branches_partial = 0 for module in modules: module_name = module.__name__ module_report_data = _build_module_report(coverage, module) sum_lines += module_report_data.n_lines_total sum_lines_not_covered += module_report_data.n_lines_missing sum_branches += module_report_data.n_branches sum_branches_missing += module_report_data.n_branches_missing sum_branches_partial += module_report_data.n_branches_partial module_report = { "module": module_name, "coverage": module_report_data.code_coverage, "sum_lines": module_report_data.n_lines_total, "lines": module_report_data.lines_total, "sum_lines_not_covered": module_report_data.n_lines_missing, "lines_not_covered": module_report_data.lines_missing, "branches": module_report_data.n_branches, "branches_partial": module_report_data.n_branches_partial, "branches_missing": module_report_data.n_branches_missing } logger.debug("Module coverage report: %s", module_report) report["module_names"].append(module_report) if module_report_data.code_coverage < threshold: msg = "Test coverage below %2d%% for %s: %2d%%" % ( threshold, module_name, module_report_data.code_coverage) logger.warn(msg) coverage_too_low = True if module_report_data.branch_coverage < branch_threshold: msg = "Branch coverage below %2d%% for %s: %2d%%" % ( branch_threshold, module_name, module_report_data.branch_coverage) logger.warn(msg) branch_coverage_too_low = True if module_report_data.branch_partial_coverage < branch_partial_threshold: msg = "Partial branch coverage below %2d%% for %s: %2d%%" % ( branch_partial_threshold, module_name, module_report_data.branch_partial_coverage) logger.warn(msg) branch_partial_coverage_too_low = True if sum_lines == 0: overall_coverage = 100 else: overall_coverage = (sum_lines - sum_lines_not_covered) * 100 / sum_lines if sum_branches == 0: overall_branch_coverage = 100 overall_branch_partial_coverage = 100 else: overall_branch_coverage = (sum_branches - sum_branches_missing) * 100 / sum_branches overall_branch_partial_coverage = ( sum_branches - sum_branches_partial) * 100 / sum_branches report["overall_coverage"] = overall_coverage report["overall_branch_coverage"] = overall_branch_coverage report["overall_branch_partial_coverage"] = overall_branch_partial_coverage if overall_coverage < threshold: logger.warn("Overall %s is below %2d%%: %2d%%", execution_name, threshold, overall_coverage) coverage_too_low = True else: logger.info("Overall %s is %2d%%", execution_name, overall_coverage) if overall_branch_coverage < branch_threshold: logger.warn("Overall %s branch coverage is below %2d%%: %2d%%", execution_name, branch_threshold, overall_branch_coverage) branch_coverage_too_low = True else: logger.info("Overall %s branch coverage is %2d%%", execution_name, overall_branch_coverage) if overall_branch_partial_coverage < branch_partial_threshold: logger.warn("Overall %s partial branch coverage is below %2d%%: %2d%%", execution_name, branch_partial_threshold, overall_branch_partial_coverage) branch_partial_coverage_too_low = True else: logger.info("Overall %s partial branch coverage is %2d%%", execution_name, overall_branch_partial_coverage) project.write_report("%s.json" % execution_prefix, render_report(report)) _write_summary_report(coverage, project, modules, execution_prefix, execution_name) if coverage_too_low and project.get_property( "%s_break_build" % execution_prefix): return BuildFailedException( "Test coverage for at least one module is below %d%%", threshold) if branch_coverage_too_low and project.get_property( "%s_break_build" % execution_prefix): return BuildFailedException( "Test branch coverage for at least one module is below %d%%", branch_threshold) if branch_partial_coverage_too_low and project.get_property( "%s_break_build" % execution_prefix): return BuildFailedException( "Test partial branch coverage for at least one module is below %d%%", branch_partial_threshold)
def do_coverage(project, logger, reactor, execution_prefix, execution_name, target_task, shortest_plan): """ This function MUST ALWAYS execute in a fork. The sys.modules will be manipulated extensively to stage the tests properly, which may affect execute down the line. It's best to simple let this method exit and the fork die rather than to try to recover. """ source_tree_path = project.get_property("dir_source_main_python") module_names = _discover_modules_to_cover(project) for module_name in module_names: logger.debug("Module '%s' coverage to be verified", module_name) _delete_non_essential_modules() __import__("pybuilder.plugins.python") # Reimport self # Starting fresh from coverage import coverage as coverage_factory coverage = coverage_factory(cover_pylib=False, branch=True, source=[source_tree_path]) try: project.set_property('__running_coverage', True) # tell other plugins that we are not really unit testing right now _start_coverage(coverage) if shortest_plan: reactor.execute_task_shortest_plan(target_task) else: reactor.execute_task(target_task) finally: _stop_coverage(coverage) project.set_property('__running_coverage', False) coverage_too_low = False threshold = project.get_property("%s_threshold_warn" % execution_prefix) exceptions = project.get_property("%s_exceptions" % execution_prefix) report = { "module_names": [] } sum_lines = 0 sum_lines_not_covered = 0 modules = [] for module_name in module_names: try: module = sys.modules[module_name] except KeyError: logger.warn("Module '%s' was not imported by the covered tests", module_name) try: module = __import__(module_name) except SyntaxError as e: logger.warn("Coverage for module '%s' cannot be established - syntax error: %s", module_name, e) continue if module not in modules: modules.append(module) module_report_data = build_module_report(coverage, module) should_ignore_module = module_name in exceptions if not should_ignore_module: sum_lines += module_report_data[0] sum_lines_not_covered += module_report_data[2] module_report = { "module": module_name, "coverage": module_report_data[4], "sum_lines": module_report_data[0], "lines": module_report_data[1], "sum_lines_not_covered": module_report_data[2], "lines_not_covered": module_report_data[3], } logger.debug("Module coverage report: %s", module_report) report["module_names"].append(module_report) if module_report_data[4] < threshold: msg = "Test coverage below %2d%% for %s: %2d%%" % (threshold, module_name, module_report_data[4]) if not should_ignore_module: logger.warn(msg) coverage_too_low = True else: logger.info(msg) if sum_lines == 0: overall_coverage = 0 else: overall_coverage = (sum_lines - sum_lines_not_covered) * 100 / sum_lines report["overall_coverage"] = overall_coverage if overall_coverage < threshold: logger.warn("Overall %s is below %2d%%: %2d%%", execution_name, threshold, overall_coverage) coverage_too_low = True else: logger.info("Overall %s is %2d%%", execution_name, overall_coverage) project.write_report("%s.json" % execution_prefix, render_report(report)) _write_summary_report(coverage, project, modules, execution_prefix, execution_name) if coverage_too_low and project.get_property("%s_break_build" % execution_prefix): raise BuildFailedException("Test coverage for at least one module is below %d%%", threshold)
def _build_coverage_report(project, logger, coverage_description, coverage_name, config_prefix, cov, source_path, module_names, module_files): coverage_too_low = False branch_coverage_too_low = False branch_partial_coverage_too_low = False threshold = project.get_property("%scoverage_threshold_warn" % config_prefix) branch_threshold = project.get_property( "%scoverage_branch_threshold_warn" % config_prefix) branch_partial_threshold = project.get_property( "%scoverage_branch_partial_threshold_warn" % config_prefix) report = {"module_names": []} sum_lines = 0 sum_lines_not_covered = 0 sum_branches = 0 sum_branches_missing = 0 sum_branches_partial = 0 from coverage import files old_relative_dir = files.RELATIVE_DIR files.RELATIVE_DIR = source_path try: for idx, module_name in enumerate(module_names): module_file = module_files[idx] module_report_data = _build_module_report(cov, module_file) sum_lines += module_report_data.n_lines_total sum_lines_not_covered += module_report_data.n_lines_missing sum_branches += module_report_data.n_branches sum_branches_missing += module_report_data.n_branches_missing sum_branches_partial += module_report_data.n_branches_partial module_report = { "module": module_name, "coverage": module_report_data.code_coverage, "sum_lines": module_report_data.n_lines_total, "lines": module_report_data.lines_total, "sum_lines_not_covered": module_report_data.n_lines_missing, "lines_not_covered": module_report_data.lines_missing, "branches": module_report_data.n_branches, "branches_partial": module_report_data.n_branches_partial, "branches_missing": module_report_data.n_branches_missing } logger.debug("Module coverage report: %s", module_report) report["module_names"].append(module_report) if module_report_data.code_coverage < threshold: msg = "Test coverage below %2d%% for %s: %2d%%" % ( threshold, module_name, module_report_data.code_coverage) logger.warn(msg) coverage_too_low = True if module_report_data.branch_coverage < branch_threshold: msg = "Branch coverage below %2d%% for %s: %2d%%" % ( branch_threshold, module_name, module_report_data.branch_coverage) logger.warn(msg) branch_coverage_too_low = True if module_report_data.branch_partial_coverage < branch_partial_threshold: msg = "Partial branch coverage below %2d%% for %s: %2d%%" % ( branch_partial_threshold, module_name, module_report_data.branch_partial_coverage) logger.warn(msg) branch_partial_coverage_too_low = True if sum_lines == 0: overall_coverage = 100 else: overall_coverage = (sum_lines - sum_lines_not_covered) * 100 / sum_lines if sum_branches == 0: overall_branch_coverage = 100 overall_branch_partial_coverage = 100 else: overall_branch_coverage = ( sum_branches - sum_branches_missing) * 100 / sum_branches overall_branch_partial_coverage = ( sum_branches - sum_branches_partial) * 100 / sum_branches report["overall_coverage"] = overall_coverage report["overall_branch_coverage"] = overall_branch_coverage report[ "overall_branch_partial_coverage"] = overall_branch_partial_coverage if overall_coverage < threshold: logger.warn("Overall %s coverage is below %2d%%: %2d%%", coverage_name, threshold, overall_coverage) coverage_too_low = True else: logger.info("Overall %s coverage is %2d%%", coverage_name, overall_coverage) if overall_branch_coverage < branch_threshold: logger.warn("Overall %s branch coverage is below %2d%%: %2d%%", coverage_name, branch_threshold, overall_branch_coverage) branch_coverage_too_low = True else: logger.info("Overall %s branch coverage is %2d%%", coverage_name, overall_branch_coverage) if overall_branch_partial_coverage < branch_partial_threshold: logger.warn( "Overall %s partial branch coverage is below %2d%%: %2d%%", coverage_name, branch_partial_threshold, overall_branch_partial_coverage) branch_partial_coverage_too_low = True else: logger.info("Overall %s partial branch coverage is %2d%%", coverage_name, overall_branch_partial_coverage) project.write_report("%s_coverage.json" % coverage_name, render_report(report)) _write_summary_report(cov, project, module_names, module_files, config_prefix, coverage_description, coverage_name) if coverage_too_low and project.get_property( "%scoverage_break_build" % config_prefix): return BuildFailedException( "Test coverage for at least one module is below %d%%", threshold) if branch_coverage_too_low and project.get_property( "%scoverage_break_build" % config_prefix): return BuildFailedException( "Test branch coverage for at least one module is below %d%%", branch_threshold) if branch_partial_coverage_too_low and project.get_property( "%scoverage_break_build" % config_prefix): return BuildFailedException( "Test partial branch coverage for at least one module is below %d%%", branch_partial_threshold) finally: files.RELATIVE_DIR = old_relative_dir
def _build_coverage_report(project, logger, execution_name, execution_prefix, coverage, modules): coverage_too_low = False branch_coverage_too_low = False branch_partial_coverage_too_low = False threshold = project.get_property("%s_threshold_warn" % execution_prefix) branch_threshold = project.get_property("%s_branch_threshold_warn" % execution_prefix) branch_partial_threshold = project.get_property("%s_branch_partial_threshold_warn" % execution_prefix) report = { "module_names": [] } sum_lines = 0 sum_lines_not_covered = 0 sum_branches = 0 sum_branches_missing = 0 sum_branches_partial = 0 for module in modules: module_name = module.__name__ module_report_data = _build_module_report(coverage, module) sum_lines += module_report_data.n_lines_total sum_lines_not_covered += module_report_data.n_lines_missing sum_branches += module_report_data.n_branches sum_branches_missing += module_report_data.n_branches_missing sum_branches_partial += module_report_data.n_branches_partial module_report = { "module": module_name, "coverage": module_report_data.code_coverage, "sum_lines": module_report_data.n_lines_total, "lines": module_report_data.lines_total, "sum_lines_not_covered": module_report_data.n_lines_missing, "lines_not_covered": module_report_data.lines_missing, "branches": module_report_data.n_branches, "branches_partial": module_report_data.n_branches_partial, "branches_missing": module_report_data.n_branches_missing } logger.debug("Module coverage report: %s", module_report) report["module_names"].append(module_report) if module_report_data.code_coverage < threshold: msg = "Test coverage below %2d%% for %s: %2d%%" % (threshold, module_name, module_report_data.code_coverage) logger.warn(msg) coverage_too_low = True if module_report_data.branch_coverage < branch_threshold: msg = "Branch coverage below %2d%% for %s: %2d%%" % ( branch_threshold, module_name, module_report_data.branch_coverage) logger.warn(msg) branch_coverage_too_low = True if module_report_data.branch_partial_coverage < branch_partial_threshold: msg = "Partial branch coverage below %2d%% for %s: %2d%%" % ( branch_partial_threshold, module_name, module_report_data.branch_partial_coverage) logger.warn(msg) branch_partial_coverage_too_low = True if sum_lines == 0: overall_coverage = 100 else: overall_coverage = (sum_lines - sum_lines_not_covered) * 100 / sum_lines if sum_branches == 0: overall_branch_coverage = 100 overall_branch_partial_coverage = 100 else: overall_branch_coverage = (sum_branches - sum_branches_missing) * 100 / sum_branches overall_branch_partial_coverage = (sum_branches - sum_branches_partial) * 100 / sum_branches report["overall_coverage"] = overall_coverage report["overall_branch_coverage"] = overall_branch_coverage report["overall_branch_partial_coverage"] = overall_branch_partial_coverage if overall_coverage < threshold: logger.warn("Overall %s is below %2d%%: %2d%%", execution_name, threshold, overall_coverage) coverage_too_low = True else: logger.info("Overall %s is %2d%%", execution_name, overall_coverage) if overall_branch_coverage < branch_threshold: logger.warn("Overall %s branch coverage is below %2d%%: %2d%%", execution_name, branch_threshold, overall_branch_coverage) branch_coverage_too_low = True else: logger.info("Overall %s branch coverage is %2d%%", execution_name, overall_branch_coverage) if overall_branch_partial_coverage < branch_partial_threshold: logger.warn("Overall %s partial branch coverage is below %2d%%: %2d%%", execution_name, branch_partial_threshold, overall_branch_partial_coverage) branch_partial_coverage_too_low = True else: logger.info("Overall %s partial branch coverage is %2d%%", execution_name, overall_branch_partial_coverage) project.write_report("%s.json" % execution_prefix, render_report(report)) _write_summary_report(coverage, project, modules, execution_prefix, execution_name) if coverage_too_low and project.get_property("%s_break_build" % execution_prefix): return BuildFailedException("Test coverage for at least one module is below %d%%", threshold) if branch_coverage_too_low and project.get_property("%s_break_build" % execution_prefix): return BuildFailedException("Test branch coverage for at least one module is below %d%%", branch_threshold) if branch_partial_coverage_too_low and project.get_property("%s_break_build" % execution_prefix): return BuildFailedException("Test partial branch coverage for at least one module is below %d%%", branch_partial_threshold)
def do_coverage(project, logger, reactor): import coverage start_coverage(coverage) reactor.execute_task("run_unit_tests") stop_coverage(coverage, project, logger) coverage_too_low = False threshold = project.get_property("coverage_threshold_warn") exceptions = project.get_property("coverage_exceptions") report = {"module_names": []} sum_lines = 0 sum_lines_not_covered = 0 module_names = discover_modules_to_cover(project) modules = [] for module_name in module_names: try: module = sys.modules[module_name] except KeyError: logger.warn("Module not imported: {0}. No coverage information available.".format(module_name)) continue modules.append(module) module_report_data = build_module_report(coverage, module) sum_lines += module_report_data[0] sum_lines_not_covered += module_report_data[2] module_report = { "module": module_name, "coverage": module_report_data[4], "sum_lines": module_report_data[0], "lines": module_report_data[1], "sum_lines_not_covered": module_report_data[2], "lines_not_covered": module_report_data[3], } report["module_names"].append(module_report) if module_report_data[4] < threshold: msg = "Test coverage below %2d%% for %s: %2d%%" % (threshold, module_name, module_report_data[4]) if module_name not in exceptions: logger.warn(msg) coverage_too_low = True else: logger.info(msg) if sum_lines == 0: overall_coverage = 0 else: overall_coverage = (sum_lines - sum_lines_not_covered) * 100 / sum_lines report["overall_coverage"] = overall_coverage if overall_coverage < threshold: logger.warn("Overall coverage is below %2d%%: %2d%%", threshold, overall_coverage) coverage_too_low = True else: logger.info("Overall coverage is %2d%%", overall_coverage) project.write_report("coverage.json", render_report(report)) write_summary_report(coverage, project, modules) if coverage_too_low and project.get_property("coverage_break_build"): raise BuildFailedException("Test coverage for at least one module is below %d%%", threshold)
def write_report_and_ensure_all_tests_passed(self): self.project.write_report("integrationtest.json", render_report(self.test_report)) self.logger.info("Executed %d integration tests.", self.tests_executed) if self.tests_failed: raise BuildFailedException("Integration test(s) failed.")
def do_coverage(project, logger, reactor): import coverage start_coverage(coverage) project.set_property( '__running_coverage', True ) # tell other plugins that we are not really unit testing right now reactor.execute_task("run_unit_tests") project.set_property('__running_coverage', False) stop_coverage(coverage, project, logger) coverage_too_low = False threshold = project.get_property("coverage_threshold_warn") exceptions = project.get_property("coverage_exceptions") report = {"module_names": []} sum_lines = 0 sum_lines_not_covered = 0 module_names = discover_modules_to_cover(project) modules = [] for module_name in module_names: try: module = sys.modules[module_name] except KeyError: logger.warn( "Module not imported: {0}. No coverage information available.". format(module_name)) continue modules.append(module) module_report_data = build_module_report(coverage, module) should_ignore_module = module_name in exceptions if not should_ignore_module: sum_lines += module_report_data[0] sum_lines_not_covered += module_report_data[2] module_report = { "module": module_name, "coverage": module_report_data[4], "sum_lines": module_report_data[0], "lines": module_report_data[1], "sum_lines_not_covered": module_report_data[2], "lines_not_covered": module_report_data[3], } report["module_names"].append(module_report) if module_report_data[4] < threshold: msg = "Test coverage below %2d%% for %s: %2d%%" % ( threshold, module_name, module_report_data[4]) if not should_ignore_module: logger.warn(msg) coverage_too_low = True else: logger.info(msg) if sum_lines == 0: overall_coverage = 0 else: overall_coverage = (sum_lines - sum_lines_not_covered) * 100 / sum_lines report["overall_coverage"] = overall_coverage if overall_coverage < threshold: logger.warn("Overall coverage is below %2d%%: %2d%%", threshold, overall_coverage) coverage_too_low = True else: logger.info("Overall coverage is %2d%%", overall_coverage) project.write_report("coverage.json", render_report(report)) write_summary_report(coverage, project, modules) if coverage_too_low and project.get_property("coverage_break_build"): raise BuildFailedException( "Test coverage for at least one module is below %d%%", threshold)
def do_coverage(project, logger, reactor, execution_prefix, execution_name, target_task, shortest_plan): from coverage import coverage as coverage_factory source_tree_path = project.get_property("dir_source_main_python") coverage = coverage_factory(cover_pylib=False, source=[source_tree_path]) _start_coverage(coverage) project.set_property('__running_coverage', True) # tell other plugins that we are not really unit testing right now if shortest_plan: reactor.execute_task_shortest_plan(target_task) else: reactor.execute_task(target_task) project.set_property('__running_coverage', False) _stop_coverage(coverage, project, logger, execution_prefix) coverage_too_low = False threshold = project.get_property("%s_threshold_warn" % execution_prefix) exceptions = project.get_property("%s_exceptions" % execution_prefix) report = { "module_names": [] } sum_lines = 0 sum_lines_not_covered = 0 module_names = _discover_modules_to_cover(project) modules = [] for module_name in module_names: try: module = sys.modules[module_name] except KeyError: logger.warn("Module not imported: {0}. No coverage information available.".format(module_name)) continue modules.append(module) module_report_data = build_module_report(coverage, module) should_ignore_module = module_name in exceptions if not should_ignore_module: sum_lines += module_report_data[0] sum_lines_not_covered += module_report_data[2] module_report = { "module": module_name, "coverage": module_report_data[4], "sum_lines": module_report_data[0], "lines": module_report_data[1], "sum_lines_not_covered": module_report_data[2], "lines_not_covered": module_report_data[3], } report["module_names"].append(module_report) if module_report_data[4] < threshold: msg = "Test coverage below %2d%% for %s: %2d%%" % (threshold, module_name, module_report_data[4]) if not should_ignore_module: logger.warn(msg) coverage_too_low = True else: logger.info(msg) if sum_lines == 0: overall_coverage = 0 else: overall_coverage = (sum_lines - sum_lines_not_covered) * 100 / sum_lines report["overall_coverage"] = overall_coverage if overall_coverage < threshold: logger.warn("Overall %s is below %2d%%: %2d%%", execution_name, threshold, overall_coverage) coverage_too_low = True else: logger.info("Overall %s is %2d%%", execution_name, overall_coverage) project.write_report("%s.json" % execution_prefix, render_report(report)) _write_summary_report(coverage, project, modules, execution_prefix) if coverage_too_low and project.get_property("%s_break_build" % execution_prefix): raise BuildFailedException("Test coverage for at least one module is below %d%%", threshold)