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