1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35 """
36 Wrapper for running Python unittest within rosunit/rostest framework.
37 """
38 from __future__ import with_statement
39
40 import sys
41
42 from .core import create_xml_runner, XML_OUTPUT_FLAG
43 from .baretest import print_unittest_summary
44
45 -def unitrun(package, test_name, test, sysargs=None, coverage_packages=None):
46 """
47 Wrapper routine from running python unitttests with
48 JUnit-compatible XML output. This is meant for unittests that do
49 not not need a running ROS graph (i.e. offline tests only).
50
51 This enables JUnit-compatible test reporting so that
52 test results can be reported to higher-level tools.
53
54 WARNING: unitrun() will trigger a sys.exit() on test failure in
55 order to properly exit with an error code. This routine is meant
56 to be used as a main() routine, not as a library.
57
58 @param package: name of ROS package that is running the test
59 @type package: str
60 @param coverage_packages: list of Python package to compute coverage results for. Defaults to package
61 @type coverage_packages: [str]
62 @param sysargs: (optional) alternate sys.argv
63 @type sysargs: [str]
64 """
65 if sysargs is None:
66
67 import sys
68 sysargs = sys.argv
69
70 import unittest
71
72 if coverage_packages is None:
73 coverage_packages = [package]
74
75
76 result_file = None
77 for arg in sysargs:
78 if arg.startswith(XML_OUTPUT_FLAG):
79 result_file = arg[len(XML_OUTPUT_FLAG):]
80 text_mode = '--text' in sysargs
81
82 coverage_mode = '--cov' in sysargs or '--covhtml' in sysargs
83 if coverage_mode:
84 start_coverage(coverage_packages)
85
86
87 suite = unittest.TestLoader().loadTestsFromTestCase(test)
88 if text_mode:
89 result = unittest.TextTestRunner(verbosity=2).run(suite)
90 else:
91 result = create_xml_runner(package, test_name, result_file).run(suite)
92 if coverage_mode:
93 cov_html_dir = 'covhtml' if '--covhtml' in sysargs else None
94 stop_coverage(coverage_packages, html=cov_html_dir)
95
96
97 print_unittest_summary(result)
98
99 if not result.wasSuccessful():
100 import sys
101 sys.exit(1)
102
103
104 _cov = None
106 global _cov
107 try:
108 import coverage
109 try:
110 _cov = coverage.coverage()
111
112 _cov.load()
113 _cov.start()
114 except coverage.CoverageException:
115 print >> sys.stderr, "WARNING: you have an older version of python-coverage that is not support. Please update to the version provided by 'easy_install coverage'"
116 except ImportError, e:
117 print >> sys.stderr, """WARNING: cannot import python-coverage, coverage tests will not run.
118 To install coverage, run 'easy_install coverage'"""
119
121 """
122 @param packages: list of packages to generate coverage reports for
123 @type packages: [str]
124 @param html: (optional) if not None, directory to generate html report to
125 @type html: str
126 """
127 if _cov is None:
128 return
129 import sys, os
130 try:
131 _cov.stop()
132
133 _cov.save()
134
135
136
137
138
139 if os.path.exists('.coverage-modules'):
140 with open('.coverage-modules','r') as f:
141 all_packages = set([x for x in f.read().split('\n') if x.strip()] + packages)
142 else:
143 all_packages = set(packages)
144 with open('.coverage-modules','w') as f:
145 f.write('\n'.join(all_packages)+'\n')
146
147 try:
148
149 all_mods = []
150
151
152 for package in packages:
153 pkg = __import__(package)
154 m = [v for v in sys.modules.values() if v and v.__name__.startswith(package)]
155 all_mods.extend(m)
156
157
158 _cov.report(m, show_missing=0)
159 for mod in m:
160 res = _cov.analysis(mod)
161 print "\n%s:\nMissing lines: %s"%(res[0], res[3])
162
163 if html:
164
165 print "="*80+"\ngenerating html coverage report to %s\n"%html+"="*80
166 _cov.html_report(all_mods, directory=html)
167 except ImportError, e:
168 print >> sys.stderr, "WARNING: cannot import '%s', will not generate coverage report"%package
169 except ImportError, e:
170 print >> sys.stderr, """WARNING: cannot import python-coverage, coverage tests will not run.
171 To install coverage, run 'easy_install coverage'"""
172