##// END OF EJS Templates
Refactored iptest to include the iptestall capabilities....
Brian Granger -
Show More
@@ -1,31 +1,39 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """IPython Test Suite Runner.
2 """IPython Test Suite Runner.
3
3
4 This module provides a main entry point to a user script to test IPython itself
4 This module provides a main entry point to a user script to test IPython
5 from the command line. The main() routine can be used in a similar manner to
5 itself from the command line. There are two ways of running this script:
6 the ``nosetests`` script, and it takes similar arguments, but if no arguments
6
7 are given it defaults to testing all of IPython. This should be preferred to
7 1. With the syntax `iptest all`. This runs our entire test suite by
8 using plain ``nosetests`` because a number of nose plugins necessary to test
8 calling this script (with different arguments) or trial recursively. This
9 IPython correctly are automatically configured by this code.
9 causes modules and package to be tested in different processes, using nose
10 or trial where appropriate.
11 2. With the regular nose syntax, like `iptest -vvs IPython`. In this form
12 the script simply calls nose, but with special command line flags and
13 plugins loaded.
14
15 For now, this script requires that both nose and twisted are installed. This
16 will change in the future.
10 """
17 """
11
18
12 #-----------------------------------------------------------------------------
19 #-----------------------------------------------------------------------------
13 # Module imports
20 # Module imports
14 #-----------------------------------------------------------------------------
21 #-----------------------------------------------------------------------------
15
22
16 # stdlib
23 import os
24 import os.path as path
17 import sys
25 import sys
26 import subprocess
27 import time
18 import warnings
28 import warnings
19
29
20 # third-party
21 import nose.plugins.builtin
30 import nose.plugins.builtin
22 from nose.core import TestProgram
31 from nose.core import TestProgram
23
32
24 # Our own imports
25 from IPython.testing.plugin.ipdoctest import IPythonDoctest
33 from IPython.testing.plugin.ipdoctest import IPythonDoctest
26
34
27 #-----------------------------------------------------------------------------
35 #-----------------------------------------------------------------------------
28 # Constants and globals
36 # Globals and constants
29 #-----------------------------------------------------------------------------
37 #-----------------------------------------------------------------------------
30
38
31 # For the IPythonDoctest plugin, we need to exclude certain patterns that cause
39 # For the IPythonDoctest plugin, we need to exclude certain patterns that cause
@@ -50,8 +58,12 b" EXCLUDE = ['IPython/external/',"
50 # Functions and classes
58 # Functions and classes
51 #-----------------------------------------------------------------------------
59 #-----------------------------------------------------------------------------
52
60
53 def main():
61 def run_iptest():
54 """Run the IPython test suite.
62 """Run the IPython test suite using nose.
63
64 This function is called when this script is **not** called with the form
65 `iptest all`. It simply calls nose with appropriate command line flags
66 and accepts all of the standard nose arguments.
55 """
67 """
56
68
57 warnings.filterwarnings('ignore',
69 warnings.filterwarnings('ignore',
@@ -101,3 +113,132 b' def main():'
101 plugins.append(plug)
113 plugins.append(plug)
102
114
103 TestProgram(argv=argv,plugins=plugins)
115 TestProgram(argv=argv,plugins=plugins)
116
117
118 class IPTester(object):
119 """Call that calls iptest or trial in a subprocess.
120 """
121 def __init__(self,runner='iptest',params=None):
122 """ """
123 if runner == 'iptest':
124 self.runner = ['iptest','-v']
125 else:
126 self.runner = ['trial']
127 if params is None:
128 params = []
129 if isinstance(params,str):
130 params = [params]
131 self.params = params
132
133 # Assemble call
134 self.call_args = self.runner+self.params
135
136 def run(self):
137 """Run the stored commands"""
138 return subprocess.call(self.call_args)
139
140
141 def make_runners():
142 """Define the modules and packages that need to be tested.
143 """
144
145 # This omits additional top-level modules that should not be doctested.
146 # XXX: Shell.py is also ommited because of a bug in the skip_doctest
147 # decorator. See ticket https://bugs.launchpad.net/bugs/366209
148 top_mod = \
149 ['background_jobs.py', 'ColorANSI.py', 'completer.py', 'ConfigLoader.py',
150 'CrashHandler.py', 'Debugger.py', 'deep_reload.py', 'demo.py',
151 'DPyGetOpt.py', 'dtutils.py', 'excolors.py', 'FakeModule.py',
152 'generics.py', 'genutils.py', 'history.py', 'hooks.py', 'ipapi.py',
153 'iplib.py', 'ipmaker.py', 'ipstruct.py', 'irunner.py', 'Itpl.py',
154 'Logger.py', 'macro.py', 'Magic.py', 'OInspect.py',
155 'OutputTrap.py', 'platutils.py', 'prefilter.py', 'Prompts.py',
156 'PyColorize.py', 'Release.py', 'rlineimpl.py', 'shadowns.py',
157 'shellglobals.py', 'strdispatch.py', 'twshell.py',
158 'ultraTB.py', 'upgrade_dir.py', 'usage.py', 'wildcard.py',
159 # See note above for why this is skipped
160 # 'Shell.py',
161 'winconsole.py']
162
163 if os.name == 'posix':
164 top_mod.append('platutils_posix.py')
165 elif sys.platform == 'win32':
166 top_mod.append('platutils_win32.py')
167 else:
168 top_mod.append('platutils_dummy.py')
169
170 top_pack = ['config','Extensions','frontend','gui','kernel',
171 'testing','tests','tools','UserConfig']
172
173 modules = ['IPython.%s' % m[:-3] for m in top_mod ]
174 packages = ['IPython.%s' % m for m in top_pack ]
175
176 # Make runners
177 runners = dict(zip(top_pack, [IPTester(params=v) for v in packages]))
178
179 try:
180 import zope.interface
181 import twisted
182 import foolscap
183 except ImportError:
184 pass
185 else:
186 runners['trial'] = IPTester('trial',['IPython'])
187
188 for m in modules:
189 runners[m] = IPTester(params=m)
190
191 return runners
192
193
194 def run_iptestall():
195 """Run the entire IPython test suite by calling nose and trial.
196
197 This function constructs :class:`IPTester` instances for all IPython
198 modules and package and then runs each of them. This causes the modules
199 and packages of IPython to be tested each in their own subprocess using
200 nose or twisted.trial appropriately.
201 """
202 runners = make_runners()
203 # Run all test runners, tracking execution time
204 failed = {}
205 t_start = time.time()
206 for name,runner in runners.iteritems():
207 print '*'*77
208 print 'IPython test set:',name
209 res = runner.run()
210 if res:
211 failed[name] = res
212 t_end = time.time()
213 t_tests = t_end - t_start
214 nrunners = len(runners)
215 nfail = len(failed)
216 # summarize results
217 print
218 print '*'*77
219 print 'Ran %s test sets in %.3fs' % (nrunners, t_tests)
220 print
221 if not failed:
222 print 'OK'
223 else:
224 # If anything went wrong, point out what command to rerun manually to
225 # see the actual errors and individual summary
226 print 'ERROR - %s out of %s test sets failed.' % (nfail, nrunners)
227 for name in failed:
228 failed_runner = runners[name]
229 print '-'*40
230 print 'Runner failed:',name
231 print 'You may wish to rerun this one individually, with:'
232 print ' '.join(failed_runner.call_args)
233 print
234
235
236 def main():
237 if sys.argv[1] == 'all':
238 run_iptestall()
239 else:
240 run_iptest()
241
242
243 if __name__ == '__main__':
244 main() No newline at end of file
1 NO CONTENT: file was removed
NO CONTENT: file was removed
General Comments 0
You need to be logged in to leave comments. Login now