1 """Supporting definitions for the Python regression tests."""
3 if __name__
!= 'test.test_support':
4 raise ImportError, 'test_support must be imported from the test package'
8 class Error(Exception):
9 """Base class for regression test exceptions."""
11 class TestFailed(Error
):
14 class TestSkipped(Error
):
17 This can be raised to indicate that a test was deliberatly
18 skipped, but not because a feature wasn't available. For
19 example, if some resource can't be used, such as the network
20 appears to be unavailable, this should be raised instead of
24 class ResourceDenied(TestSkipped
):
25 """Test skipped because it requested a disallowed resource.
27 This is raised when a test calls requires() for a resource that
28 has not be enabled. It is used to distinguish between expected
32 verbose
= 1 # Flag set to 0 by regrtest.py
33 use_resources
= None # Flag set to [] by regrtest.py
35 # _original_stdout is meant to hold stdout at the time regrtest began.
36 # This may be "the real" stdout, or IDLE's emulation of stdout, or whatever.
37 # The point is to have some flavor of stdout the user can actually see.
38 _original_stdout
= None
39 def record_original_stdout(stdout
):
40 global _original_stdout
41 _original_stdout
= stdout
43 def get_original_stdout():
44 return _original_stdout
or sys
.stdout
53 '''"Forget" a module was ever imported by removing it from sys.modules and
54 deleting any .pyc and .pyo files.'''
57 for dirname
in sys
.path
:
59 os
.unlink(os
.path
.join(dirname
, modname
+ os
.extsep
+ 'pyc'))
62 # Deleting the .pyo file cannot be within the 'try' for the .pyc since
63 # the chance exists that there is no .pyc (and thus the 'try' statement
64 # is exited) but there is a .pyo file.
66 os
.unlink(os
.path
.join(dirname
, modname
+ os
.extsep
+ 'pyo'))
70 def is_resource_enabled(resource
):
71 """Test whether a resource is enabled. Known resources are set by
73 return use_resources
is not None and resource
in use_resources
75 def requires(resource
, msg
=None):
76 """Raise ResourceDenied if the specified resource is not available.
78 If the caller's module is __main__ then automatically return True. The
79 possibility of False being returned occurs when regrtest.py is executing."""
80 # see if the caller's module is __main__ - if so, treat as if
81 # the resource was set
82 if sys
._getframe
().f_back
.f_globals
.get("__name__") == "__main__":
84 if not is_resource_enabled(resource
):
86 msg
= "Use of the `%s' resource not enabled" % resource
87 raise ResourceDenied(msg
)
91 def fcmp(x
, y
): # fuzzy comparison function
92 if type(x
) == type(0.0) or type(y
) == type(0.0):
95 fuzz
= (abs(x
) + abs(y
)) * FUZZ
100 elif type(x
) == type(y
) and type(x
) in (type(()), type([])):
101 for i
in range(min(len(x
), len(y
))):
102 outcome
= fcmp(x
[i
], y
[i
])
105 return cmp(len(x
), len(y
))
114 is_jython
= sys
.platform
.startswith('java')
117 # Filename used for testing
118 if os
.name
== 'java':
119 # Jython disallows @ in module names
121 elif os
.name
== 'riscos':
125 # Unicode name only used if TEST_FN_ENCODING exists for the platform.
127 # Assuming sys.getfilesystemencoding()!=sys.getdefaultencoding()
128 # TESTFN_UNICODE is a filename that can be encoded using the
129 # file system encoding, but *not* with the default (ascii) encoding
130 if isinstance('', unicode):
132 # XXX perhaps unicode() should accept Unicode strings?
133 TESTFN_UNICODE
= "@test-\xe0\xf2"
135 # 2 latin characters.
136 TESTFN_UNICODE
= unicode("@test-\xe0\xf2", "latin-1")
137 TESTFN_ENCODING
= sys
.getfilesystemencoding()
138 # TESTFN_UNICODE_UNENCODEABLE is a filename that should *not* be
139 # able to be encoded by *either* the default or filesystem encoding.
140 # This test really only makes sense on Windows NT platforms
141 # which have special Unicode support in posixmodule.
142 if (not hasattr(sys
, "getwindowsversion") or
143 sys
.getwindowsversion()[3] < 2): # 0=win32s or 1=9x/ME
144 TESTFN_UNICODE_UNENCODEABLE
= None
146 # Japanese characters (I think - from bug 846133)
147 TESTFN_UNICODE_UNENCODEABLE
= eval('u"@test-\u5171\u6709\u3055\u308c\u308b"')
149 # XXX - Note - should be using TESTFN_ENCODING here - but for
150 # Windows, "mbcs" currently always operates as if in
151 # errors=ignore' mode - hence we get '?' characters rather than
152 # the exception. 'Latin1' operates as we expect - ie, fails.
153 # See [ 850997 ] mbcs encoding ignores errors
154 TESTFN_UNICODE_UNENCODEABLE
.encode("Latin1")
155 except UnicodeEncodeError:
159 'WARNING: The filename %r CAN be encoded by the filesystem. ' \
160 'Unicode filename tests may not be effective' \
161 % TESTFN_UNICODE_UNENCODEABLE
163 # Make sure we can write to TESTFN, try in /tmp if we can't
166 fp
= open(TESTFN
, 'w+')
168 TMP_TESTFN
= os
.path
.join('/tmp', TESTFN
)
170 fp
= open(TMP_TESTFN
, 'w+')
174 print ('WARNING: tests will fail, unable to write to: %s or %s' %
175 (TESTFN
, TMP_TESTFN
))
184 from os
import unlink
186 def findfile(file, here
=__file__
):
187 """Try to find a file on sys.path and the working directory. If it is not
188 found the argument passed to the function is returned (this does not
189 necessarily signal failure; could still be the legitimate path)."""
191 if os
.path
.isabs(file):
194 path
= [os
.path
.dirname(here
)] + path
196 fn
= os
.path
.join(dn
, file)
197 if os
.path
.exists(fn
): return fn
200 def verify(condition
, reason
='test failed'):
201 """Verify that condition is true. If not, raise TestFailed.
203 The optional argument reason can be given to provide
208 raise TestFailed(reason
)
211 """Raise TestFailed if a == b is false.
213 This is better than verify(a == b) because, in case of failure, the
214 error message incorporates repr(a) and repr(b) so you can see the
217 Note that "not (a == b)" isn't necessarily the same as "a != b"; the
222 raise TestFailed
, "%r == %r" % (a
, b
)
225 "Like repr(dict), but in sorted order."
228 reprpairs
= ["%r: %r" % pair
for pair
in items
]
229 withcommas
= ", ".join(reprpairs
)
230 return "{%s}" % withcommas
232 def check_syntax(statement
):
234 compile(statement
, '<string>', 'exec')
238 print 'Missing SyntaxError: "%s"' % statement
240 def open_urlresource(url
):
241 import urllib
, urlparse
244 filename
= urlparse
.urlparse(url
)[2].split('/')[-1] # '/': it's URL!
246 for path
in [os
.path
.curdir
, os
.path
.pardir
]:
247 fn
= os
.path
.join(path
, filename
)
248 if os
.path
.exists(fn
):
252 print >> get_original_stdout(), '\tfetching %s ...' % url
253 fn
, _
= urllib
.urlretrieve(url
, filename
)
256 #=======================================================================
257 # Preliminary PyUNIT integration.
262 class BasicTestRunner
:
264 result
= unittest
.TestResult()
269 def run_suite(suite
, testclass
=None):
270 """Run tests from a unittest.TestSuite-derived class."""
272 runner
= unittest
.TextTestRunner(sys
.stdout
, verbosity
=2)
274 runner
= BasicTestRunner()
276 result
= runner
.run(suite
)
277 if not result
.wasSuccessful():
278 if len(result
.errors
) == 1 and not result
.failures
:
279 err
= result
.errors
[0][1]
280 elif len(result
.failures
) == 1 and not result
.errors
:
281 err
= result
.failures
[0][1]
283 if testclass
is None:
284 msg
= "errors occurred; run in verbose mode for details"
286 msg
= "errors occurred in %s.%s" \
287 % (testclass
.__module
__, testclass
.__name
__)
288 raise TestFailed(msg
)
289 raise TestFailed(err
)
292 def run_unittest(*classes
):
293 """Run tests from unittest.TestCase-derived classes."""
294 suite
= unittest
.TestSuite()
296 if isinstance(cls
, (unittest
.TestSuite
, unittest
.TestCase
)):
299 suite
.addTest(unittest
.makeSuite(cls
))
301 testclass
= classes
[0]
304 run_suite(suite
, testclass
)
307 #=======================================================================
310 def run_doctest(module
, verbosity
=None):
311 """Run doctest on the given module. Return (#failures, #tests).
313 If optional argument verbosity is not specified (or is None), pass
314 test_support's belief about verbosity on to doctest. Else doctest's
315 usual behavior is used (it searches sys.argv for -v).
320 if verbosity
is None:
325 # Direct doctest output (normally just errors) to real stdout; doctest
326 # output shouldn't be compared by regrtest.
327 save_stdout
= sys
.stdout
328 sys
.stdout
= get_original_stdout()
330 f
, t
= doctest
.testmod(module
, verbose
=verbosity
)
332 raise TestFailed("%d of %d doctests failed" % (f
, t
))
334 sys
.stdout
= save_stdout
336 print 'doctest (%s) ... %d tests with zero failures' % (module
.__name
__, t
)