Пример #1
0
 def html_data_from_cov(self, cov, morf):
     """Get HTML report data from a `Coverage` object for a morf."""
     with self.assert_warnings(cov, []):
         datagen = coverage.html.HtmlDataGeneration(cov)
         fr, analysis = next(get_analysis_to_report(cov, [morf]))
         file_data = datagen.data_for_file(fr, analysis)
         return file_data
Пример #2
0
    def report(self, morfs):
        """Generate an HTML report for `morfs`.

        `morfs` is a list of modules or file names.

        """
        # Read the status data and check that this run used the same
        # global data as the last run.
        self.incr.read()
        self.incr.check_global_data(self.config, self.pyfile_html_source)

        # Process all the files.
        for fr, analysis in get_analysis_to_report(self.coverage, morfs):
            self.html_file(fr, analysis)

        if not self.all_files_nums:
            raise CoverageException("No data to report.")

        self.totals = sum(self.all_files_nums)

        # Write the index file.
        self.index_file()

        self.make_local_static_report_files()
        return self.totals.n_statements and self.totals.pc_covered
Пример #3
0
    def get_coverage(args: list, root_path: str, module_use=False) -> Dict[str, Line]:
        """
        Returns Dict of covered line's Line object.
         :param args: list of module name and target testcase want to get coverage
         :param root_path: target src root want to get coverage
         :return: {
             Line1_hash: {file_path, line_no, line_text},
             Line2_hash: {file_path, line_no, line_text}
         }
        1. cover 한 라인 (file path, line no, line text)
        2. file path 가 root 에 포함되는가.
        2. Line(line text, line no, file path)
        3. res_dict[Line.getHash()] = Line
        4. return res_dict
        """

        regular_path = os.path.abspath(root_path)
        covered = defaultdict(Line)
        # path 에 해당하는 .py file run.
        # report 에 covered line 정보 담겨있음.
        cov = Coverage()
        # args = args[:1] + [root_path] + args[1:]
        runner = PyRunner(args, as_module=module_use)
        runner.prepare()

        cov.start()
        code_ran = True
        try:
            runner.run()
        except NoSource:
            code_ran = False
            raise
        finally:
            cov.stop()
            if code_ran:
                cov.save()

            # testcase.py args 없다고 가정.
            report = get_analysis_to_report(cov, [])
            try:
                for fr, analysis in report:
                    # report : [(file1, [line1, line2, ...]), (), ...]
                    fn = fr.filename
                    if regular_path not in fn:
                        continue

                    if os.path.splitext(fn)[-1] != ".py":
                        continue

                    with open(fn, 'r', encoding="UTF8") as f:
                        lines = f.readlines()
                        if lines:
                            for line_no in analysis.executed:
                                lo = Line(fr.filename, line_no, lines[line_no-1])
                                covered[lo.getHash()] = lo
                        f.close()
            except CoverageException:
                print("There is no Test ran")

            return covered
Пример #4
0
def html_data_from_cov(cov, morf):
    """Get HTML report data from a `Coverage` object for a morf."""
    datagen = coverage.html.HtmlDataGeneration(cov)
    for fr, analysis in get_analysis_to_report(cov, [morf]):
        # This will only loop once, so it's fine to return inside the loop.
        file_data = datagen.data_for_file(fr, analysis)
        return file_data
Пример #5
0
    def report(self, morfs, directory=None):
        """Run the report.

        See `coverage.report()` for arguments.

        """
        self.directory = directory
        self.coverage.get_data()
        for fr, analysis in get_analysis_to_report(self.coverage, morfs):
            self.annotate_file(fr, analysis)
Пример #6
0
    def report(self, morfs, outfile=None):
        """Generate a json report for `morfs`.

        `morfs` is a list of modules or file names.

        `outfile` is a file object to write the json to

        """
        outfile = outfile or sys.stdout
        coverage_data = self.coverage.get_data()
        coverage_data.set_query_contexts(self.config.report_contexts)
        self.report_data["meta"] = {
            "version": __version__,
            "timestamp": datetime.datetime.now().isoformat(),
            "branch_coverage": coverage_data.has_arcs(),
            "show_contexts": self.config.json_show_contexts,
        }

        measured_files = {}
        for file_reporter, analysis in get_analysis_to_report(
                self.coverage, morfs):
            measured_files[
                file_reporter.relative_filename()] = self.report_one_file(
                    coverage_data, analysis)

        self.report_data["files"] = measured_files

        self.report_data["totals"] = {
            'covered_lines': self.total.n_executed,
            'num_statements': self.total.n_statements,
            'percent_covered': self.total.pc_covered,
            'percent_covered_display': self.total.pc_covered_str,
            'missing_lines': self.total.n_missing,
            'excluded_lines': self.total.n_excluded,
        }

        if coverage_data.has_arcs():
            self.report_data["totals"].update({
                'num_branches':
                self.total.n_branches,
                'num_partial_branches':
                self.total.n_partial_branches,
                'covered_branches':
                self.total.n_executed_branches,
                'missing_branches':
                self.total.n_missing_branches,
            })

        json.dump(self.report_data,
                  outfile,
                  indent=4 if self.config.json_pretty_print else None)

        return self.total.n_statements and self.total.pc_covered
Пример #7
0
    def report(self, morfs, outfile=None):
        """Renders the full lcov report.

        'morfs' is a list of modules or filenames

        outfile is the file object to write the file into.
        """

        self.coverage.get_data()
        outfile = outfile or sys.stdout

        for fr, analysis in get_analysis_to_report(self.coverage, morfs):
            self.get_lcov(fr, analysis, outfile)
Пример #8
0
    def report(self, morfs, outfile=None):
        """Writes a report summarizing coverage statistics per module.

        `outfile` is a file object to write the summary to. It must be opened
        for native strings (bytes on Python 2, Unicode on Python 3).

        """
        self.outfile = outfile or sys.stdout

        self.coverage.get_data().set_query_contexts(
            self.config.report_contexts)
        for fr, analysis in get_analysis_to_report(self.coverage, morfs):
            self.report_one_file(fr, analysis)

        # Prepare the formatting strings, header, and column sorting.
        max_name = max([
            len(fr.relative_filename()) for (fr, analysis) in self.fr_analysis
        ] + [5])
        fmt_name = "%%- %ds  " % max_name
        fmt_skip_covered = "\n%s file%s skipped due to complete coverage."
        fmt_skip_empty = "\n%s empty file%s skipped."

        header = (fmt_name % "Name") + " Stmts   Miss"
        fmt_coverage = fmt_name + "%6d %6d"
        if self.branches:
            header += " Branch BrPart"
            fmt_coverage += " %6d %6d"
        width100 = Numbers(precision=self.config.precision).pc_str_width()
        header += "%*s" % (width100 + 4, "Cover")
        fmt_coverage += "%%%ds%%%%" % (width100 + 3, )
        if self.config.show_missing:
            header += "   Missing"
            fmt_coverage += "   %s"
        rule = "-" * len(header)

        column_order = dict(name=0, stmts=1, miss=2, cover=-1)
        if self.branches:
            column_order.update(dict(branch=3, brpart=4))

        # Write the header
        self.writeout(header)
        self.writeout(rule)

        # `lines` is a list of pairs, (line text, line values).  The line text
        # is a string that will be printed, and line values is a tuple of
        # sortable values.
        lines = []

        for (fr, analysis) in self.fr_analysis:
            nums = analysis.numbers

            args = (fr.relative_filename(), nums.n_statements, nums.n_missing)
            if self.branches:
                args += (nums.n_branches, nums.n_partial_branches)
            args += (nums.pc_covered_str, )
            if self.config.show_missing:
                args += (analysis.missing_formatted(branches=True), )
            text = fmt_coverage % args
            # Add numeric percent coverage so that sorting makes sense.
            args += (nums.pc_covered, )
            lines.append((text, args))

        # Sort the lines and write them out.
        sort_option = (self.config.sort or "name").lower()
        reverse = False
        if sort_option[0] == '-':
            reverse = True
            sort_option = sort_option[1:]
        elif sort_option[0] == '+':
            sort_option = sort_option[1:]

        if sort_option == "name":
            lines = human_sorted_items(lines, reverse=reverse)
        else:
            position = column_order.get(sort_option)
            if position is None:
                raise CoverageException(
                    f"Invalid sorting option: {self.config.sort!r}")
            lines.sort(key=lambda l: (l[1][position], l[0]), reverse=reverse)

        for line in lines:
            self.writeout(line[0])

        # Write a TOTAL line if we had at least one file.
        if self.total.n_files > 0:
            self.writeout(rule)
            args = ("TOTAL", self.total.n_statements, self.total.n_missing)
            if self.branches:
                args += (self.total.n_branches, self.total.n_partial_branches)
            args += (self.total.pc_covered_str, )
            if self.config.show_missing:
                args += ("", )
            self.writeout(fmt_coverage % args)

        # Write other final lines.
        if not self.total.n_files and not self.skipped_count:
            raise CoverageException("No data to report.")

        if self.config.skip_covered and self.skipped_count:
            self.writeout(
                fmt_skip_covered %
                (self.skipped_count, 's' if self.skipped_count > 1 else ''))
        if self.config.skip_empty and self.empty_count:
            self.writeout(
                fmt_skip_empty %
                (self.empty_count, 's' if self.empty_count > 1 else ''))

        return self.total.n_statements and self.total.pc_covered
 def find_file_reporters(self, morfs):
     return [
         fr for fr, _ in get_analysis_to_report(
             self.coverage, morfs)
     ]
Пример #10
0
    def report(self, morfs, outfile=None):
        """Writes a report summarizing coverage statistics per module.

        `outfile` is a file object to write the summary to. It must be opened
        for native strings (bytes on Python 2, Unicode on Python 3).

        """
        self.outfile = outfile or sys.stdout

        self.coverage.get_data().set_query_contexts(self.config.report_contexts)
        for fr, analysis in get_analysis_to_report(self.coverage, morfs):
            self.report_one_file(fr, analysis)

        # Prepare the formatting strings, header, and column sorting.
        max_name = max([len(fr.relative_filename()) for (fr, analysis) in self.fr_analysis] + [5])
        fmt_name = u"%%- %ds  " % max_name
        fmt_skip_covered = u"\n%s file%s skipped due to complete coverage."
        fmt_skip_empty = u"\n%s empty file%s skipped."

        header = (fmt_name % "Name") + u" Stmts   Miss"
        fmt_coverage = fmt_name + u"%6d %6d"
        if self.branches:
            header += u" Branch BrPart"
            fmt_coverage += u" %6d %6d"
        width100 = Numbers.pc_str_width()
        header += u"%*s" % (width100+4, "Cover")
        fmt_coverage += u"%%%ds%%%%" % (width100+3,)
        if self.config.show_missing:
            header += u"   Missing"
            fmt_coverage += u"   %s"
        rule = u"-" * len(header)

        column_order = dict(name=0, stmts=1, miss=2, cover=-1)
        if self.branches:
            column_order.update(dict(branch=3, brpart=4))

        # Write the header
        self.writeout(header)
        self.writeout(rule)

        # `lines` is a list of pairs, (line text, line values).  The line text
        # is a string that will be printed, and line values is a tuple of
        # sortable values.
        lines = []

        for (fr, analysis) in self.fr_analysis:
            try:
                nums = analysis.numbers

                args = (fr.relative_filename(), nums.n_statements, nums.n_missing)
                if self.branches:
                    args += (nums.n_branches, nums.n_partial_branches)
                args += (nums.pc_covered_str,)
                if self.config.show_missing:
                    args += (analysis.missing_formatted(branches=True),)
                text = fmt_coverage % args
                # Add numeric percent coverage so that sorting makes sense.
                args += (nums.pc_covered,)
                lines.append((text, args))
            except Exception:
                report_it = not self.config.ignore_errors
                if report_it:
                    typ, msg = sys.exc_info()[:2]
                    # NotPython is only raised by PythonFileReporter, which has a
                    # should_be_python() method.
                    if typ is NotPython and not fr.should_be_python():
                        report_it = False
                if report_it:
                    self.writeout(self.fmt_err % (fr.relative_filename(), typ.__name__, msg))

        # Sort the lines and write them out.
        if getattr(self.config, 'sort', None):
            position = column_order.get(self.config.sort.lower())
            if position is None:
                raise CoverageException("Invalid sorting option: {!r}".format(self.config.sort))
            lines.sort(key=lambda l: (l[1][position], l[0]))

        for line in lines:
            self.writeout(line[0])

        # Write a TOTAl line if we had more than one file.
        if self.total.n_files > 1:
            self.writeout(rule)
            args = ("TOTAL", self.total.n_statements, self.total.n_missing)
            if self.branches:
                args += (self.total.n_branches, self.total.n_partial_branches)
            args += (self.total.pc_covered_str,)
            if self.config.show_missing:
                args += ("",)
            self.writeout(fmt_coverage % args)

        # Write other final lines.
        if not self.total.n_files and not self.skipped_count:
            raise CoverageException("No data to report.")

        if self.config.skip_covered and self.skipped_count:
            self.writeout(
                fmt_skip_covered % (self.skipped_count, 's' if self.skipped_count > 1 else '')
                )
        if self.config.skip_empty and self.empty_count:
            self.writeout(
                fmt_skip_empty % (self.empty_count, 's' if self.empty_count > 1 else '')
                )

        return self.total.n_statements and self.total.pc_covered
Пример #11
0
    def report(self, morfs, outfile=None):
        """Generate a Cobertura-compatible XML report for `morfs`.

        `morfs` is a list of modules or file names.

        `outfile` is a file object to write the XML to.

        """
        # Initial setup.
        outfile = outfile or sys.stdout
        has_arcs = self.coverage.get_data().has_arcs()

        # Create the DOM that will store the data.
        impl = xml.dom.minidom.getDOMImplementation()
        self.xml_out = impl.createDocument(None, "coverage", None)

        # Write header stuff.
        xcoverage = self.xml_out.documentElement
        xcoverage.setAttribute("version", __version__)
        xcoverage.setAttribute("timestamp", str(int(time.time()*1000)))
        xcoverage.appendChild(self.xml_out.createComment(
            " Generated by coverage.py: %s " % __url__
            ))
        xcoverage.appendChild(self.xml_out.createComment(" Based on %s " % DTD_URL))

        # Call xml_file for each file in the data.
        for fr, analysis in get_analysis_to_report(self.coverage, morfs):
            self.xml_file(fr, analysis, has_arcs)

        xsources = self.xml_out.createElement("sources")
        xcoverage.appendChild(xsources)

        # Populate the XML DOM with the source info.
        for path in sorted(self.source_paths):
            xsource = self.xml_out.createElement("source")
            xsources.appendChild(xsource)
            txt = self.xml_out.createTextNode(path)
            xsource.appendChild(txt)

        lnum_tot, lhits_tot = 0, 0
        bnum_tot, bhits_tot = 0, 0

        xpackages = self.xml_out.createElement("packages")
        xcoverage.appendChild(xpackages)

        # Populate the XML DOM with the package info.
        for pkg_name, pkg_data in sorted(iitems(self.packages)):
            class_elts, lhits, lnum, bhits, bnum = pkg_data
            xpackage = self.xml_out.createElement("package")
            xpackages.appendChild(xpackage)
            xclasses = self.xml_out.createElement("classes")
            xpackage.appendChild(xclasses)
            for _, class_elt in sorted(iitems(class_elts)):
                xclasses.appendChild(class_elt)
            xpackage.setAttribute("name", pkg_name.replace(os.sep, '.'))
            xpackage.setAttribute("line-rate", rate(lhits, lnum))
            if has_arcs:
                branch_rate = rate(bhits, bnum)
            else:
                branch_rate = "0"
            xpackage.setAttribute("branch-rate", branch_rate)
            xpackage.setAttribute("complexity", "0")

            lnum_tot += lnum
            lhits_tot += lhits
            bnum_tot += bnum
            bhits_tot += bhits

        xcoverage.setAttribute("lines-valid", str(lnum_tot))
        xcoverage.setAttribute("lines-covered", str(lhits_tot))
        xcoverage.setAttribute("line-rate", rate(lhits_tot, lnum_tot))
        if has_arcs:
            xcoverage.setAttribute("branches-valid", str(bnum_tot))
            xcoverage.setAttribute("branches-covered", str(bhits_tot))
            xcoverage.setAttribute("branch-rate", rate(bhits_tot, bnum_tot))
        else:
            xcoverage.setAttribute("branches-covered", "0")
            xcoverage.setAttribute("branches-valid", "0")
            xcoverage.setAttribute("branch-rate", "0")
        xcoverage.setAttribute("complexity", "0")

        # Write the output file.
        outfile.write(serialize_xml(self.xml_out))

        # Return the total percentage.
        denom = lnum_tot + bnum_tot
        if denom == 0:
            pct = 0.0
        else:
            pct = 100.0 * (lhits_tot + bhits_tot) / denom
        return pct