1 """Supporting definitions for the Python regression test."""
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
55 for dirname
in sys
.path
:
57 os
.unlink(os
.path
.join(dirname
, modname
+ '.pyc'))
61 def is_resource_enabled(resource
):
62 return use_resources
is not None and resource
in use_resources
64 def requires(resource
, msg
=None):
65 # see if the caller's module is __main__ - if so, treat as if
66 # the resource was set
67 if sys
._getframe
().f_back
.f_globals
.get("__name__") == "__main__":
69 if not is_resource_enabled(resource
):
71 msg
= "Use of the `%s' resource not enabled" % resource
72 raise ResourceDenied(msg
)
76 def fcmp(x
, y
): # fuzzy comparison function
77 if type(x
) == type(0.0) or type(y
) == type(0.0):
80 fuzz
= (abs(x
) + abs(y
)) * FUZZ
85 elif type(x
) == type(y
) and type(x
) in (type(()), type([])):
86 for i
in range(min(len(x
), len(y
))):
87 outcome
= fcmp(x
[i
], y
[i
])
90 return cmp(len(x
), len(y
))
99 is_jython
= sys
.platform
.startswith('java')
102 # Filename used for testing
103 if os
.name
== 'java':
104 # Jython disallows @ in module names
106 elif os
.name
!= 'riscos':
108 # Unicode name only used if TEST_FN_ENCODING exists for the platform.
110 if isinstance('', unicode):
112 # XXX perhaps unicode() should accept Unicode strings?
113 TESTFN_UNICODE
="@test-\xe0\xf2"
115 TESTFN_UNICODE
=unicode("@test-\xe0\xf2", "latin-1") # 2 latin characters.
116 TESTFN_ENCODING
=sys
.getfilesystemencoding()
120 # Make sure we can write to TESTFN, try in /tmp if we can't
123 fp
= open(TESTFN
, 'w+')
125 TMP_TESTFN
= os
.path
.join('/tmp', TESTFN
)
127 fp
= open(TMP_TESTFN
, 'w+')
131 print ('WARNING: tests will fail, unable to write to: %s or %s' %
132 (TESTFN
, TMP_TESTFN
))
141 from os
import unlink
143 def findfile(file, here
=__file__
):
145 if os
.path
.isabs(file):
148 path
= [os
.path
.dirname(here
)] + path
150 fn
= os
.path
.join(dn
, file)
151 if os
.path
.exists(fn
): return fn
154 def verify(condition
, reason
='test failed'):
155 """Verify that condition is true. If not, raise TestFailed.
157 The optional argument reason can be given to provide
162 raise TestFailed(reason
)
165 """Raise TestFailed if a == b is false.
167 This is better than verify(a == b) because, in case of failure, the
168 error message incorporates repr(a) and repr(b) so you can see the
171 Note that "not (a == b)" isn't necessarily the same as "a != b"; the
176 raise TestFailed
, "%r == %r" % (a
, b
)
179 "Like repr(dict), but in sorted order."
182 reprpairs
= ["%r: %r" % pair
for pair
in items
]
183 withcommas
= ", ".join(reprpairs
)
184 return "{%s}" % withcommas
186 def check_syntax(statement
):
188 compile(statement
, '<string>', 'exec')
192 print 'Missing SyntaxError: "%s"' % statement
196 #=======================================================================
197 # Preliminary PyUNIT integration.
202 class BasicTestRunner
:
204 result
= unittest
.TestResult()
209 def run_suite(suite
, testclass
=None):
210 """Run tests from a unittest.TestSuite-derived class."""
212 runner
= unittest
.TextTestRunner(sys
.stdout
, verbosity
=2)
214 runner
= BasicTestRunner()
216 result
= runner
.run(suite
)
217 if not result
.wasSuccessful():
218 if len(result
.errors
) == 1 and not result
.failures
:
219 err
= result
.errors
[0][1]
220 elif len(result
.failures
) == 1 and not result
.errors
:
221 err
= result
.failures
[0][1]
223 if testclass
is None:
224 msg
= "errors occurred; run in verbose mode for details"
226 msg
= "errors occurred in %s.%s" \
227 % (testclass
.__module
__, testclass
.__name
__)
228 raise TestFailed(msg
)
229 raise TestFailed(err
)
232 def run_unittest(testclass
):
233 """Run tests from a unittest.TestCase-derived class."""
234 run_suite(unittest
.makeSuite(testclass
), testclass
)
237 #=======================================================================
240 def run_doctest(module
, verbosity
=None):
241 """Run doctest on the given module. Return (#failures, #tests).
243 If optional argument verbosity is not specified (or is None), pass
244 test_support's belief about verbosity on to doctest. Else doctest's
245 usual behavior is used (it searches sys.argv for -v).
250 if verbosity
is None:
255 # Direct doctest output (normally just errors) to real stdout; doctest
256 # output shouldn't be compared by regrtest.
257 save_stdout
= sys
.stdout
258 sys
.stdout
= get_original_stdout()
260 f
, t
= doctest
.testmod(module
, verbose
=verbosity
)
262 raise TestFailed("%d of %d doctests failed" % (f
, t
))
265 sys
.stdout
= save_stdout