##// END OF EJS Templates
Making the doctest exclude paths os independent.
Brian Granger -
Show More
@@ -1,245 +1,247 b''
1 1 # -*- coding: utf-8 -*-
2 2 """IPython Test Suite Runner.
3 3
4 4 This module provides a main entry point to a user script to test IPython
5 5 itself from the command line. There are two ways of running this script:
6 6
7 7 1. With the syntax `iptest all`. This runs our entire test suite by
8 8 calling this script (with different arguments) or trial recursively. This
9 9 causes modules and package to be tested in different processes, using nose
10 10 or trial where appropriate.
11 11 2. With the regular nose syntax, like `iptest -vvs IPython`. In this form
12 12 the script simply calls nose, but with special command line flags and
13 13 plugins loaded.
14 14
15 15 For now, this script requires that both nose and twisted are installed. This
16 16 will change in the future.
17 17 """
18 18
19 19 #-----------------------------------------------------------------------------
20 20 # Module imports
21 21 #-----------------------------------------------------------------------------
22 22
23 23 import os
24 24 import os.path as path
25 25 import sys
26 26 import subprocess
27 27 import time
28 28 import warnings
29 29
30 30 import nose.plugins.builtin
31 31 from nose.core import TestProgram
32 32
33 33 from IPython.testing.plugin.ipdoctest import IPythonDoctest
34 34
35 pjoin = path.join
36
35 37 #-----------------------------------------------------------------------------
36 38 # Globals and constants
37 39 #-----------------------------------------------------------------------------
38 40
39 41 # For the IPythonDoctest plugin, we need to exclude certain patterns that cause
40 42 # testing problems. We should strive to minimize the number of skipped
41 43 # modules, since this means untested code. As the testing machinery
42 44 # solidifies, this list should eventually become empty.
43 EXCLUDE = ['IPython/external/',
44 'IPython/platutils_win32',
45 'IPython/frontend/cocoa',
46 'IPython/frontend/process/winprocess.py',
47 'IPython_doctest_plugin',
48 'IPython/Gnuplot',
49 'IPython/Extensions/ipy_',
50 'IPython/Extensions/clearcmd',
51 'IPython/Extensions/PhysicalQIn',
52 'IPython/Extensions/scitedirector',
53 'IPython/Extensions/numeric_formats',
54 'IPython/testing/attic',
45 EXCLUDE = [pjoin('IPython', 'external'),
46 pjoin('IPython', 'platutils_win32'),
47 pjoin('IPython', 'frontend', 'cocoa'),
48 pjoin('IPython', 'frontend', 'process', 'winprocess.py'),
49 pjoin('IPython_doctest_plugin'),
50 pjoin('IPython', 'Gnuplot'),
51 pjoin('IPython', 'Extensions', 'ipy_'),
52 pjoin('IPython', 'Extensions', 'clearcmd'),
53 pjoin('IPython', 'Extensions', 'PhysicalQIn'),
54 pjoin('IPython', 'Extensions', 'scitedirector'),
55 pjoin('IPython', 'Extensions', 'numeric_formats'),
56 pjoin('IPython', 'testing', 'attic'),
55 57 ]
56 58
57 59 #-----------------------------------------------------------------------------
58 60 # Functions and classes
59 61 #-----------------------------------------------------------------------------
60 62
61 63 def run_iptest():
62 64 """Run the IPython test suite using nose.
63 65
64 66 This function is called when this script is **not** called with the form
65 67 `iptest all`. It simply calls nose with appropriate command line flags
66 68 and accepts all of the standard nose arguments.
67 69 """
68 70
69 71 warnings.filterwarnings('ignore',
70 72 'This will be removed soon. Use IPython.testing.util instead')
71 73
72 74 argv = sys.argv + [
73 75 # Loading ipdoctest causes problems with Twisted.
74 76 # I am removing this as a temporary fix to get the
75 77 # test suite back into working shape. Our nose
76 78 # plugin needs to be gone through with a fine
77 79 # toothed comb to find what is causing the problem.
78 80 '--with-ipdoctest',
79 81 '--ipdoctest-tests','--ipdoctest-extension=txt',
80 82 '--detailed-errors',
81 83
82 84 # We add --exe because of setuptools' imbecility (it
83 85 # blindly does chmod +x on ALL files). Nose does the
84 86 # right thing and it tries to avoid executables,
85 87 # setuptools unfortunately forces our hand here. This
86 88 # has been discussed on the distutils list and the
87 89 # setuptools devs refuse to fix this problem!
88 90 '--exe',
89 91 ]
90 92
91 93 # Detect if any tests were required by explicitly calling an IPython
92 94 # submodule or giving a specific path
93 95 has_tests = False
94 96 for arg in sys.argv:
95 97 if 'IPython' in arg or arg.endswith('.py') or \
96 98 (':' in arg and '.py' in arg):
97 99 has_tests = True
98 100 break
99 101
100 102 # If nothing was specifically requested, test full IPython
101 103 if not has_tests:
102 104 argv.append('IPython')
103 105
104 106 # Construct list of plugins, omitting the existing doctest plugin, which
105 107 # ours replaces (and extends).
106 108 plugins = [IPythonDoctest(EXCLUDE)]
107 109 for p in nose.plugins.builtin.plugins:
108 110 plug = p()
109 111 if plug.name == 'doctest':
110 112 continue
111 113
112 114 #print '*** adding plugin:',plug.name # dbg
113 115 plugins.append(plug)
114 116
115 117 TestProgram(argv=argv,plugins=plugins)
116 118
117 119
118 120 class IPTester(object):
119 121 """Call that calls iptest or trial in a subprocess.
120 122 """
121 123 def __init__(self,runner='iptest',params=None):
122 124 """ """
123 125 if runner == 'iptest':
124 126 self.runner = ['iptest','-v']
125 127 else:
126 128 self.runner = ['trial']
127 129 if params is None:
128 130 params = []
129 131 if isinstance(params,str):
130 132 params = [params]
131 133 self.params = params
132 134
133 135 # Assemble call
134 136 self.call_args = self.runner+self.params
135 137
136 138 def run(self):
137 139 """Run the stored commands"""
138 140 return subprocess.call(self.call_args)
139 141
140 142
141 143 def make_runners():
142 144 """Define the modules and packages that need to be tested.
143 145 """
144 146
145 147 # This omits additional top-level modules that should not be doctested.
146 148 # XXX: Shell.py is also ommited because of a bug in the skip_doctest
147 149 # decorator. See ticket https://bugs.launchpad.net/bugs/366209
148 150 top_mod = \
149 151 ['background_jobs.py', 'ColorANSI.py', 'completer.py', 'ConfigLoader.py',
150 152 'CrashHandler.py', 'Debugger.py', 'deep_reload.py', 'demo.py',
151 153 'DPyGetOpt.py', 'dtutils.py', 'excolors.py', 'FakeModule.py',
152 154 'generics.py', 'genutils.py', 'history.py', 'hooks.py', 'ipapi.py',
153 155 'iplib.py', 'ipmaker.py', 'ipstruct.py', 'irunner.py', 'Itpl.py',
154 156 'Logger.py', 'macro.py', 'Magic.py', 'OInspect.py',
155 157 'OutputTrap.py', 'platutils.py', 'prefilter.py', 'Prompts.py',
156 158 'PyColorize.py', 'Release.py', 'rlineimpl.py', 'shadowns.py',
157 159 'shellglobals.py', 'strdispatch.py', 'twshell.py',
158 160 'ultraTB.py', 'upgrade_dir.py', 'usage.py', 'wildcard.py',
159 161 # See note above for why this is skipped
160 162 # 'Shell.py',
161 163 'winconsole.py']
162 164
163 165 if os.name == 'posix':
164 166 top_mod.append('platutils_posix.py')
165 167 elif sys.platform == 'win32':
166 168 top_mod.append('platutils_win32.py')
167 169 else:
168 170 top_mod.append('platutils_dummy.py')
169 171
170 172 # These are tested by nose, so skip IPython.kernel
171 173 top_pack = ['config','Extensions','frontend','gui',
172 174 'testing','tests','tools','UserConfig']
173 175
174 176 modules = ['IPython.%s' % m[:-3] for m in top_mod ]
175 177 packages = ['IPython.%s' % m for m in top_pack ]
176 178
177 179 # Make runners
178 180 runners = dict(zip(top_pack, [IPTester(params=v) for v in packages]))
179 181
180 182 # Test IPython.kernel using trial if twisted is installed
181 183 try:
182 184 import zope.interface
183 185 import twisted
184 186 import foolscap
185 187 except ImportError:
186 188 pass
187 189 else:
188 190 runners['trial'] = IPTester('trial',['IPython'])
189 191
190 192 runners['modules'] = IPTester(params=modules)
191 193
192 194 return runners
193 195
194 196
195 197 def run_iptestall():
196 198 """Run the entire IPython test suite by calling nose and trial.
197 199
198 200 This function constructs :class:`IPTester` instances for all IPython
199 201 modules and package and then runs each of them. This causes the modules
200 202 and packages of IPython to be tested each in their own subprocess using
201 203 nose or twisted.trial appropriately.
202 204 """
203 205 runners = make_runners()
204 206 # Run all test runners, tracking execution time
205 207 failed = {}
206 208 t_start = time.time()
207 209 for name,runner in runners.iteritems():
208 210 print '*'*77
209 211 print 'IPython test set:',name
210 212 res = runner.run()
211 213 if res:
212 214 failed[name] = res
213 215 t_end = time.time()
214 216 t_tests = t_end - t_start
215 217 nrunners = len(runners)
216 218 nfail = len(failed)
217 219 # summarize results
218 220 print
219 221 print '*'*77
220 222 print 'Ran %s test sets in %.3fs' % (nrunners, t_tests)
221 223 print
222 224 if not failed:
223 225 print 'OK'
224 226 else:
225 227 # If anything went wrong, point out what command to rerun manually to
226 228 # see the actual errors and individual summary
227 229 print 'ERROR - %s out of %s test sets failed.' % (nfail, nrunners)
228 230 for name in failed:
229 231 failed_runner = runners[name]
230 232 print '-'*40
231 233 print 'Runner failed:',name
232 234 print 'You may wish to rerun this one individually, with:'
233 235 print ' '.join(failed_runner.call_args)
234 236 print
235 237
236 238
237 239 def main():
238 240 if sys.argv[1] == 'all':
239 241 run_iptestall()
240 242 else:
241 243 run_iptest()
242 244
243 245
244 246 if __name__ == '__main__':
245 247 main() No newline at end of file
General Comments 0
You need to be logged in to leave comments. Login now