2 """A Trial IReporter plugin that gathers coverage.py code-coverage information.
4 Once this plugin is installed, trial can be invoked a new --reporter option:
6 trial --reporter-bwverbose-coverage ARGS
8 Once such a test run has finished, there will be a .coverage file in the
9 top-level directory. This file can be turned into a directory of .html files
10 (with index.html as the starting point) by running:
12 coverage html -d OUTPUTDIR --omit=PREFIX1,PREFIX2,..
14 The 'coverage' tool thinks in terms of absolute filenames. 'coverage' doesn't
15 record data for files that come with Python, but it does record data for all
16 the various site-package directories. To show only information for Tahoe
17 source code files, you should provide --omit prefixes for everything else.
18 This probably means something like:
20 --omit=/System/,/Library/,support/,src/allmydata/test/
22 Before using this, you need to install the 'coverage' package, which will
23 provide an executable tool named 'coverage' (as well as an importable
24 library). 'coverage report' will produce a basic text summary of the coverage
25 data. Our 'misc/coverage2text.py' tool produces a slightly more useful
26 summary, and 'misc/coverage2html.py' will produce a more useful HTML report.
30 from twisted.trial.reporter import TreeReporter, VerboseTextReporter
32 # These plugins are registered via twisted/plugins/allmydata_trial.py . See
33 # the notes there for an explanation of how that works.
35 # Some notes about how trial Reporters are used:
36 # * Reporters don't really get told about the suite starting and stopping.
37 # * The Reporter class is imported before the test classes are.
38 # * The test classes are imported before the Reporter is created. To get
39 # control earlier than that requires modifying twisted/scripts/trial.py
40 # * Then Reporter.__init__ is called.
41 # * Then tests run, calling things like write() and addSuccess(). Each test is
42 # framed by a startTest/stopTest call.
43 # * Then the results are emitted, calling things like printErrors,
44 # printSummary, and wasSuccessful.
45 # So for code-coverage (not including import), start in __init__ and finish
46 # in printSummary. To include import, we have to start in our own import and
47 # finish in printSummary.
50 cov = coverage.coverage()
54 class CoverageTextReporter(VerboseTextReporter):
55 def __init__(self, *args, **kwargs):
56 VerboseTextReporter.__init__(self, *args, **kwargs)
58 def stop_coverage(self):
61 print "Coverage results written to .coverage"
62 def printSummary(self):
65 return VerboseTextReporter.printSummary(self)
69 return VerboseTextReporter.done(self)
71 class sample_Reporter(object):
72 # this class, used as a reporter on a fully-passing test suite, doesn't
73 # trigger exceptions. So it is a guide to what methods are invoked on a
75 def __init__(self, *args, **kwargs):
77 self.r = TreeReporter(*args, **kwargs)
78 self.shouldStop = self.r.shouldStop
79 self.separator = self.r.separator
80 self.testsRun = self.r.testsRun
81 self._starting2 = False
83 def write(self, *args):
84 if not self._starting2:
85 self._starting2 = True
87 return self.r.write(*args)
89 def startTest(self, *args, **kwargs):
90 return self.r.startTest(*args, **kwargs)
92 def stopTest(self, *args, **kwargs):
93 return self.r.stopTest(*args, **kwargs)
95 def addSuccess(self, *args, **kwargs):
96 return self.r.addSuccess(*args, **kwargs)
98 def printErrors(self, *args, **kwargs):
99 return self.r.printErrors(*args, **kwargs)
101 def writeln(self, *args, **kwargs):
102 return self.r.writeln(*args, **kwargs)
104 def printSummary(self, *args, **kwargs):
105 print "PRINT SUMMARY"
106 return self.r.printSummary(*args, **kwargs)
108 def wasSuccessful(self, *args, **kwargs):
109 return self.r.wasSuccessful(*args, **kwargs)