Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cpython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
cpython
Commits
5ddd1a8d
Commit
5ddd1a8d
authored
Mar 22, 2001
by
Steve Purcell
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Updated to latest PyUnit version (1.31 in PyUnit CVS); test_support.py
changed accordingly.
parent
2e2cded1
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
244 additions
and
256 deletions
+244
-256
Lib/test/test_support.py
Lib/test/test_support.py
+6
-10
Lib/unittest.py
Lib/unittest.py
+238
-246
No files found.
Lib/test/test_support.py
View file @
5ddd1a8d
...
@@ -102,12 +102,9 @@ def check_syntax(statement):
...
@@ -102,12 +102,9 @@ def check_syntax(statement):
import
unittest
import
unittest
class
BasicTestRunner
(
unittest
.
VerboseTextTestRunner
):
class
BasicTestRunner
:
def
__init__
(
self
,
stream
=
sys
.
stderr
):
unittest
.
VerboseTextTestRunner
.
__init__
(
self
,
stream
,
descriptions
=
0
)
def
run
(
self
,
test
):
def
run
(
self
,
test
):
result
=
unittest
.
_VerboseTextTestResult
(
self
.
stream
,
descriptions
=
0
)
result
=
unittest
.
TestResult
(
)
test
(
result
)
test
(
result
)
return
result
return
result
...
@@ -115,13 +112,12 @@ class BasicTestRunner(unittest.VerboseTextTestRunner):
...
@@ -115,13 +112,12 @@ class BasicTestRunner(unittest.VerboseTextTestRunner):
def
run_unittest
(
testclass
):
def
run_unittest
(
testclass
):
"""Run tests from a unittest.TestCase-derived class."""
"""Run tests from a unittest.TestCase-derived class."""
if
verbose
:
if
verbose
:
f
=
sys
.
stdout
runner
=
unittest
.
TextTestRunner
(
sys
.
stdout
,
descriptions
=
0
)
else
:
else
:
import
StringIO
runner
=
BasicTestRunner
()
f
=
StringIO
.
StringIO
()
suite
=
unittest
.
makeSuite
(
testclass
)
suite
=
unittest
.
makeSuite
(
testclass
)
result
=
BasicTestRunner
(
stream
=
f
)
.
run
(
suite
)
result
=
runner
.
run
(
suite
)
if
result
.
errors
or
result
.
failures
:
if
not
result
.
wasSuccessful
()
:
raise
TestFailed
(
"errors occurred in %s.%s"
raise
TestFailed
(
"errors occurred in %s.%s"
%
(
testclass
.
__module__
,
testclass
.
__name__
))
%
(
testclass
.
__module__
,
testclass
.
__name__
))
Lib/unittest.py
View file @
5ddd1a8d
#!/usr/bin/env python
#!/usr/bin/env python
"""
'''
Python unit testing framework, based on Erich Gamma's JUnit and Kent Beck's
Python unit testing framework, based on Erich Gamma's JUnit and Kent Beck's
Smalltalk testing framework.
Smalltalk testing framework.
Further information is available in the bundled documentation, and from
http://pyunit.sourceforge.net/
This module contains the core framework classes that form the basis of
This module contains the core framework classes that form the basis of
specific test cases and suites (TestCase, TestSuite etc.), and also a
specific test cases and suites (TestCase, TestSuite etc.), and also a
text-based utility class for running the tests and reporting the results
text-based utility class for running the tests and reporting the results
(TextTestRunner).
(TextTestRunner).
Simple usage:
import unittest
class IntegerArithmenticTestCase(unittest.TestCase):
def testAdd(self): ## test method names begin 'test*'
self.assertEquals((1 + 2), 3)
self.assertEquals(0 + 1, 1)
def testMultiply(self);
self.assertEquals((0 * 10), 0)
self.assertEquals((5 * 8), 40)
if __name__ == '__main__':
unittest.main()
Further information is available in the bundled documentation, and from
http://pyunit.sourceforge.net/
Copyright (c) 1999, 2000, 2001 Steve Purcell
Copyright (c) 1999, 2000, 2001 Steve Purcell
This module is free software, and you may redistribute it and/or modify
This module is free software, and you may redistribute it and/or modify
it under the same terms as Python itself, so long as this copyright message
it under the same terms as Python itself, so long as this copyright message
...
@@ -27,9 +42,10 @@ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
...
@@ -27,9 +42,10 @@ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE. THE CODE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS,
PARTICULAR PURPOSE. THE CODE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS,
AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
"""
'''
__author__
=
"Steve Purcell (stephen_purcell@yahoo.com)"
__author__
=
"Steve Purcell"
__email__
=
"stephen_purcell at yahoo dot com"
__version__
=
"$Revision$"
[
11
:
-
2
]
__version__
=
"$Revision$"
[
11
:
-
2
]
import
time
import
time
...
@@ -37,15 +53,7 @@ import sys
...
@@ -37,15 +53,7 @@ import sys
import
traceback
import
traceback
import
string
import
string
import
os
import
os
import
types
##############################################################################
# A platform-specific concession to help the code work for JPython users
##############################################################################
plat
=
string
.
lower
(
sys
.
platform
)
_isJPython
=
string
.
find
(
plat
,
'java'
)
>=
0
or
string
.
find
(
plat
,
'jdk'
)
>=
0
del
plat
##############################################################################
##############################################################################
# Test framework core
# Test framework core
...
@@ -84,6 +92,10 @@ class TestResult:
...
@@ -84,6 +92,10 @@ class TestResult:
"Called when a failure has occurred"
"Called when a failure has occurred"
self
.
failures
.
append
((
test
,
err
))
self
.
failures
.
append
((
test
,
err
))
def
addSuccess
(
self
,
test
):
"Called when a test has completed successfully"
pass
def
wasSuccessful
(
self
):
def
wasSuccessful
(
self
):
"Tells whether or not this result was a success"
"Tells whether or not this result was a success"
return
len
(
self
.
failures
)
==
len
(
self
.
errors
)
==
0
return
len
(
self
.
failures
)
==
len
(
self
.
errors
)
==
0
...
@@ -101,17 +113,23 @@ class TestResult:
...
@@ -101,17 +113,23 @@ class TestResult:
class
TestCase
:
class
TestCase
:
"""A class whose instances are single test cases.
"""A class whose instances are single test cases.
Test authors should subclass TestCase for their own tests. Construction
and deconstruction of the test's environment ('fixture') can be
implemented by overriding the 'setUp' and 'tearDown' methods respectively.
By default, the test code itself should be placed in a method named
By default, the test code itself should be placed in a method named
'runTest'.
'runTest'.
If the fixture may be used for many test cases, create as
If the fixture may be used for many test cases, create as
many test methods as are needed. When instantiating such a TestCase
many test methods as are needed. When instantiating such a TestCase
subclass, specify in the constructor arguments the name of the test method
subclass, specify in the constructor arguments the name of the test method
that the instance is to execute.
that the instance is to execute.
Test authors should subclass TestCase for their own tests. Construction
and deconstruction of the test's environment ('fixture') can be
implemented by overriding the 'setUp' and 'tearDown' methods respectively.
If it is necessary to override the __init__ method, the base class
__init__ method must always be called. It is important that subclasses
should not change the signature of their __init__ method, since instances
of the classes are instantiated automatically by parts of the framework
in order to be run.
"""
"""
def
__init__
(
self
,
methodName
=
'runTest'
):
def
__init__
(
self
,
methodName
=
'runTest'
):
"""Create an instance of the class that will use the named test
"""Create an instance of the class that will use the named test
...
@@ -119,7 +137,9 @@ class TestCase:
...
@@ -119,7 +137,9 @@ class TestCase:
not have a method with the specified name.
not have a method with the specified name.
"""
"""
try
:
try
:
self
.
__testMethod
=
getattr
(
self
,
methodName
)
self
.
__testMethodName
=
methodName
testMethod
=
getattr
(
self
,
methodName
)
self
.
__testMethodDoc
=
testMethod
.
__doc__
except
AttributeError
:
except
AttributeError
:
raise
ValueError
,
"no such test method in %s: %s"
%
\
raise
ValueError
,
"no such test method in %s: %s"
%
\
(
self
.
__class__
,
methodName
)
(
self
.
__class__
,
methodName
)
...
@@ -145,18 +165,18 @@ class TestCase:
...
@@ -145,18 +165,18 @@ class TestCase:
The default implementation of this method returns the first line of
The default implementation of this method returns the first line of
the specified test method's docstring.
the specified test method's docstring.
"""
"""
doc
=
self
.
__testMethod
.
__doc__
doc
=
self
.
__testMethod
Doc
return
doc
and
string
.
strip
(
string
.
split
(
doc
,
"
\
n
"
)[
0
])
or
None
return
doc
and
string
.
strip
(
string
.
split
(
doc
,
"
\
n
"
)[
0
])
or
None
def
id
(
self
):
def
id
(
self
):
return
"%s.%s"
%
(
self
.
__class__
,
self
.
__testMethod
.
__name__
)
return
"%s.%s"
%
(
self
.
__class__
,
self
.
__testMethod
Name
)
def
__str__
(
self
):
def
__str__
(
self
):
return
"%s (%s)"
%
(
self
.
__testMethod
.
__name__
,
self
.
__class__
)
return
"%s (%s)"
%
(
self
.
__testMethod
Name
,
self
.
__class__
)
def
__repr__
(
self
):
def
__repr__
(
self
):
return
"<%s testMethod=%s>"
%
\
return
"<%s testMethod=%s>"
%
\
(
self
.
__class__
,
self
.
__testMethod
.
__name__
)
(
self
.
__class__
,
self
.
__testMethod
Name
)
def
run
(
self
,
result
=
None
):
def
run
(
self
,
result
=
None
):
return
self
(
result
)
return
self
(
result
)
...
@@ -164,6 +184,7 @@ class TestCase:
...
@@ -164,6 +184,7 @@ class TestCase:
def
__call__
(
self
,
result
=
None
):
def
__call__
(
self
,
result
=
None
):
if
result
is
None
:
result
=
self
.
defaultTestResult
()
if
result
is
None
:
result
=
self
.
defaultTestResult
()
result
.
startTest
(
self
)
result
.
startTest
(
self
)
testMethod
=
getattr
(
self
,
self
.
__testMethodName
)
try
:
try
:
try
:
try
:
self
.
setUp
()
self
.
setUp
()
...
@@ -171,8 +192,10 @@ class TestCase:
...
@@ -171,8 +192,10 @@ class TestCase:
result
.
addError
(
self
,
self
.
__exc_info
())
result
.
addError
(
self
,
self
.
__exc_info
())
return
return
ok
=
0
try
:
try
:
self
.
__testMethod
()
testMethod
()
ok
=
1
except
AssertionError
,
e
:
except
AssertionError
,
e
:
result
.
addFailure
(
self
,
self
.
__exc_info
())
result
.
addFailure
(
self
,
self
.
__exc_info
())
except
:
except
:
...
@@ -182,12 +205,15 @@ class TestCase:
...
@@ -182,12 +205,15 @@ class TestCase:
self
.
tearDown
()
self
.
tearDown
()
except
:
except
:
result
.
addError
(
self
,
self
.
__exc_info
())
result
.
addError
(
self
,
self
.
__exc_info
())
ok
=
0
if
ok
:
result
.
addSuccess
(
self
)
finally
:
finally
:
result
.
stopTest
(
self
)
result
.
stopTest
(
self
)
def
debug
(
self
):
def
debug
(
self
):
"""Run the test without collecting errors in a TestResult"""
self
.
setUp
()
self
.
setUp
()
self
.
__testMethod
()
getattr
(
self
,
self
.
__testMethodName
)
()
self
.
tearDown
()
self
.
tearDown
()
def
assert_
(
self
,
expr
,
msg
=
None
):
def
assert_
(
self
,
expr
,
msg
=
None
):
...
@@ -220,10 +246,26 @@ class TestCase:
...
@@ -220,10 +246,26 @@ class TestCase:
else
:
excName
=
str
(
excClass
)
else
:
excName
=
str
(
excClass
)
raise
AssertionError
,
excName
raise
AssertionError
,
excName
def
assertEquals
(
self
,
first
,
second
,
msg
=
None
):
"""Assert that the two objects are equal as determined by the '=='
operator.
"""
self
.
assert_
((
first
==
second
),
msg
or
'%s != %s'
%
(
first
,
second
))
def
assertNotEquals
(
self
,
first
,
second
,
msg
=
None
):
"""Assert that the two objects are unequal as determined by the '!='
operator.
"""
self
.
assert_
((
first
!=
second
),
msg
or
'%s == %s'
%
(
first
,
second
))
assertEqual
=
assertEquals
assertNotEqual
=
assertNotEquals
def
fail
(
self
,
msg
=
None
):
def
fail
(
self
,
msg
=
None
):
"""Fail immediately, with the given message."""
"""Fail immediately, with the given message."""
raise
AssertionError
,
msg
raise
AssertionError
,
msg
def
__exc_info
(
self
):
def
__exc_info
(
self
):
"""Return a version of sys.exc_info() with the traceback frame
"""Return a version of sys.exc_info() with the traceback frame
minimised; usually the top level of the traceback frame is not
minimised; usually the top level of the traceback frame is not
...
@@ -278,8 +320,8 @@ class TestSuite:
...
@@ -278,8 +320,8 @@ class TestSuite:
return
result
return
result
def
debug
(
self
):
def
debug
(
self
):
"""Run the tests without collecting errors in a TestResult"""
for
test
in
self
.
_tests
:
test
.
debug
()
for
test
in
self
.
_tests
:
test
.
debug
()
class
FunctionTestCase
(
TestCase
):
class
FunctionTestCase
(
TestCase
):
...
@@ -327,84 +369,100 @@ class FunctionTestCase(TestCase):
...
@@ -327,84 +369,100 @@ class FunctionTestCase(TestCase):
##############################################################################
##############################################################################
#
Convenience function
s
#
Locating and loading test
s
##############################################################################
##############################################################################
def
getTestCaseNames
(
testCaseClass
,
prefix
,
sortUsing
=
cmp
):
class
TestLoader
:
"""Extracts all the names of functions in the given test case class
"""This class is responsible for loading tests according to various
and its base classes that start with the given prefix. This is used
criteria and returning them wrapped in a Test
by makeSuite().
"""
It can load all tests within a given, module
testFnNames
=
filter
(
lambda
n
,
p
=
prefix
:
n
[:
len
(
p
)]
==
p
,
dir
(
testCaseClass
))
for
baseclass
in
testCaseClass
.
__bases__
:
testFnNames
=
testFnNames
+
\
getTestCaseNames
(
baseclass
,
prefix
,
sortUsing
=
None
)
if
sortUsing
:
testFnNames
.
sort
(
sortUsing
)
return
testFnNames
def
makeSuite
(
testCaseClass
,
prefix
=
'test'
,
sortUsing
=
cmp
):
"""Returns a TestSuite instance built from all of the test functions
in the given test case class whose names begin with the given
prefix. The cases are sorted by their function names
using the supplied comparison function, which defaults to 'cmp'.
"""
"""
cases
=
map
(
testCaseClass
,
testMethodPrefix
=
'test'
getTestCaseNames
(
testCaseClass
,
prefix
,
sortUsing
))
sortTestMethodsUsing
=
cmp
return
TestSuite
(
cases
)
suiteClass
=
TestSuite
def
loadTestsFromTestCase
(
self
,
testCaseClass
):
return
self
.
suiteClass
(
map
(
testCaseClass
,
self
.
getTestCaseNames
(
testCaseClass
)))
def
createTestInstance
(
name
,
module
=
None
):
def
loadTestsFromModule
(
self
,
module
):
"""Finds tests by their name, optionally only within the given module.
tests
=
[]
for
name
in
dir
(
module
):
obj
=
getattr
(
module
,
name
)
if
type
(
obj
)
==
types
.
ClassType
and
issubclass
(
obj
,
TestCase
):
tests
.
append
(
self
.
loadTestsFromTestCase
(
obj
))
return
self
.
suiteClass
(
tests
)
def
loadTestsFromName
(
self
,
name
,
module
=
None
):
parts
=
string
.
split
(
name
,
'.'
)
if
module
is
None
:
if
not
parts
:
raise
ValueError
,
"incomplete test name: %s"
%
name
else
:
module
=
__import__
(
parts
)
parts
=
parts
[
1
:]
obj
=
module
for
part
in
parts
:
obj
=
getattr
(
obj
,
part
)
if
type
(
obj
)
==
types
.
ModuleType
:
return
self
.
loadTestsFromModule
(
obj
)
elif
type
(
obj
)
==
types
.
ClassType
and
issubclass
(
obj
,
TestCase
):
return
self
.
loadTestsFromTestCase
(
obj
)
elif
type
(
obj
)
==
types
.
UnboundMethodType
:
return
obj
.
im_class
(
obj
.
__name__
)
elif
callable
(
obj
):
test
=
obj
()
if
not
isinstance
(
test
,
TestCase
)
and
\
not
isinstance
(
test
,
TestSuite
):
raise
ValueError
,
\
"calling %s returned %s, not a test"
%
obj
,
test
return
test
else
:
raise
ValueError
,
"don't know how to make test from: %s"
%
obj
Return the newly-constructed test, ready to run. If the name contains a ':'
def
loadTestsFromNames
(
self
,
names
,
module
=
None
):
then the portion of the name after the colon is used to find a specific
suites
=
[]
test case within the test case class named before the colon.
for
name
in
names
:
suites
.
append
(
self
.
loadTestsFromName
(
name
,
module
))
return
self
.
suiteClass
(
suites
)
Examples:
def
getTestCaseNames
(
self
,
testCaseClass
):
findTest('examples.listtests.suite')
testFnNames
=
filter
(
lambda
n
,
p
=
self
.
testMethodPrefix
:
n
[:
len
(
p
)]
==
p
,
-- returns result of calling 'suite'
dir
(
testCaseClass
))
findTest('examples.listtests.ListTestCase:checkAppend')
for
baseclass
in
testCaseClass
.
__bases__
:
-- returns result of calling ListTestCase('checkAppend')
for
testFnName
in
self
.
getTestCaseNames
(
baseclass
):
findTest('examples.listtests.ListTestCase:check-')
if
testFnName
not
in
testFnNames
:
# handle overridden methods
-- returns result of calling makeSuite(ListTestCase, prefix="check")
testFnNames
.
append
(
testFnName
)
"""
if
self
.
sortTestMethodsUsing
:
testFnNames
.
sort
(
self
.
sortTestMethodsUsing
)
spec
=
string
.
split
(
name
,
':'
)
return
testFnNames
if
len
(
spec
)
>
2
:
raise
ValueError
,
"illegal test name: %s"
%
name
if
len
(
spec
)
==
1
:
testName
=
spec
[
0
]
caseName
=
None
defaultTestLoader
=
TestLoader
()
else
:
testName
,
caseName
=
spec
parts
=
string
.
split
(
testName
,
'.'
)
##############################################################################
if
module
is
None
:
# Patches for old functions: these functions should be considered obsolete
if
len
(
parts
)
<
2
:
##############################################################################
raise
ValueError
,
"incomplete test name: %s"
%
name
constructor
=
__import__
(
string
.
join
(
parts
[:
-
1
],
'.'
))
def
_makeLoader
(
prefix
,
sortUsing
,
suiteClass
=
None
):
parts
=
parts
[
1
:]
loader
=
TestLoader
()
else
:
loader
.
sortTestMethodsUsing
=
sortUsing
constructor
=
module
loader
.
testMethodPrefix
=
prefix
for
part
in
parts
:
if
suiteClass
:
loader
.
suiteClass
=
suiteClass
constructor
=
getattr
(
constructor
,
part
)
return
loader
if
not
callable
(
constructor
):
raise
ValueError
,
"%s is not a callable object"
%
constructor
def
getTestCaseNames
(
testCaseClass
,
prefix
,
sortUsing
=
cmp
):
if
caseName
:
return
_makeLoader
(
prefix
,
sortUsing
).
getTestCaseNames
(
testCaseClass
)
if
caseName
[
-
1
]
==
'-'
:
prefix
=
caseName
[:
-
1
]
def
makeSuite
(
testCaseClass
,
prefix
=
'test'
,
sortUsing
=
cmp
,
suiteClass
=
TestSuite
):
if
not
prefix
:
return
_makeLoader
(
prefix
,
sortUsing
,
suiteClass
).
loadTestsFromTestCase
(
testCaseClass
)
raise
ValueError
,
"prefix too short: %s"
%
name
test
=
makeSuite
(
constructor
,
prefix
=
prefix
)
def
findTestCases
(
module
,
prefix
=
'test'
,
sortUsing
=
cmp
,
suiteClass
=
TestSuite
):
else
:
return
_makeLoader
(
prefix
,
sortUsing
,
suiteClass
).
loadTestsFromModule
(
module
)
test
=
constructor
(
caseName
)
else
:
test
=
constructor
()
if
not
hasattr
(
test
,
"countTestCases"
):
raise
TypeError
,
\
"object %s found with spec %s is not a test"
%
(
test
,
name
)
return
test
##############################################################################
##############################################################################
...
@@ -415,181 +473,107 @@ class _WritelnDecorator:
...
@@ -415,181 +473,107 @@ class _WritelnDecorator:
"""Used to decorate file-like objects with a handy 'writeln' method"""
"""Used to decorate file-like objects with a handy 'writeln' method"""
def
__init__
(
self
,
stream
):
def
__init__
(
self
,
stream
):
self
.
stream
=
stream
self
.
stream
=
stream
if
_isJPython
:
import
java.lang.System
self
.
linesep
=
java
.
lang
.
System
.
getProperty
(
"line.separator"
)
else
:
self
.
linesep
=
os
.
linesep
def
__getattr__
(
self
,
attr
):
def
__getattr__
(
self
,
attr
):
return
getattr
(
self
.
stream
,
attr
)
return
getattr
(
self
.
stream
,
attr
)
def
writeln
(
self
,
*
args
):
def
writeln
(
self
,
*
args
):
if
args
:
apply
(
self
.
write
,
args
)
if
args
:
apply
(
self
.
write
,
args
)
self
.
write
(
self
.
linesep
)
self
.
write
(
'
\
n
'
)
# text-mode streams translate to \r\n if needed
class
_JUnitTextTestResult
(
TestResult
):
"""A test result class that can print formatted text results to a stream.
Used by JUnitTextTestRunner.
"""
def
__init__
(
self
,
stream
):
self
.
stream
=
stream
TestResult
.
__init__
(
self
)
def
addError
(
self
,
test
,
error
):
TestResult
.
addError
(
self
,
test
,
error
)
self
.
stream
.
write
(
'E'
)
self
.
stream
.
flush
()
if
error
[
0
]
is
KeyboardInterrupt
:
self
.
shouldStop
=
1
def
addFailure
(
self
,
test
,
error
):
TestResult
.
addFailure
(
self
,
test
,
error
)
self
.
stream
.
write
(
'F'
)
self
.
stream
.
flush
()
def
startTest
(
self
,
test
):
TestResult
.
startTest
(
self
,
test
)
self
.
stream
.
write
(
'.'
)
self
.
stream
.
flush
()
def
printNumberedErrors
(
self
,
errFlavour
,
errors
):
if
not
errors
:
return
if
len
(
errors
)
==
1
:
self
.
stream
.
writeln
(
"There was 1 %s:"
%
errFlavour
)
else
:
self
.
stream
.
writeln
(
"There were %i %ss:"
%
(
len
(
errors
),
errFlavour
))
i
=
1
for
test
,
error
in
errors
:
errString
=
string
.
join
(
apply
(
traceback
.
format_exception
,
error
),
""
)
self
.
stream
.
writeln
(
"%i) %s"
%
(
i
,
test
))
self
.
stream
.
writeln
(
errString
)
i
=
i
+
1
def
printErrors
(
self
):
self
.
printNumberedErrors
(
"error"
,
self
.
errors
)
def
printFailures
(
self
):
self
.
printNumberedErrors
(
"failure"
,
self
.
failures
)
def
printHeader
(
self
):
self
.
stream
.
writeln
()
if
self
.
wasSuccessful
():
self
.
stream
.
writeln
(
"OK (%i tests)"
%
self
.
testsRun
)
else
:
self
.
stream
.
writeln
(
"!!!FAILURES!!!"
)
self
.
stream
.
writeln
(
"Test Results"
)
self
.
stream
.
writeln
()
self
.
stream
.
writeln
(
"Run: %i ; Failures: %i ; Errors: %i"
%
(
self
.
testsRun
,
len
(
self
.
failures
),
len
(
self
.
errors
)))
def
printResult
(
self
):
self
.
printHeader
()
self
.
printErrors
()
self
.
printFailures
()
class
_TextTestResult
(
TestResult
):
class
JUnitTextTestRunner
:
"""A test runner class that displays results in textual form.
The display format approximates that of JUnit's 'textui' test runner.
This test runner may be removed in a future version of PyUnit.
"""
def
__init__
(
self
,
stream
=
sys
.
stderr
):
self
.
stream
=
_WritelnDecorator
(
stream
)
def
run
(
self
,
test
):
"Run the given test case or test suite."
result
=
_JUnitTextTestResult
(
self
.
stream
)
startTime
=
time
.
time
()
test
(
result
)
stopTime
=
time
.
time
()
self
.
stream
.
writeln
()
self
.
stream
.
writeln
(
"Time: %.3fs"
%
float
(
stopTime
-
startTime
))
result
.
printResult
()
return
result
##############################################################################
# Verbose text UI
##############################################################################
class
_VerboseTextTestResult
(
TestResult
):
"""A test result class that can print formatted text results to a stream.
"""A test result class that can print formatted text results to a stream.
Used by
Verbose
TextTestRunner.
Used by TextTestRunner.
"""
"""
def
__init__
(
self
,
stream
,
descriptions
):
separator1
=
'='
*
70
separator2
=
'-'
*
70
def
__init__
(
self
,
stream
,
descriptions
,
verbosity
):
TestResult
.
__init__
(
self
)
TestResult
.
__init__
(
self
)
self
.
stream
=
stream
self
.
stream
=
stream
self
.
lastFailure
=
None
self
.
showAll
=
verbosity
>
1
self
.
dots
=
verbosity
==
1
self
.
descriptions
=
descriptions
self
.
descriptions
=
descriptions
def
startTest
(
self
,
test
):
def
getDescription
(
self
,
test
):
TestResult
.
startTest
(
self
,
test
)
if
self
.
descriptions
:
if
self
.
descriptions
:
self
.
stream
.
write
(
test
.
shortDescription
()
or
str
(
test
)
)
return
test
.
shortDescription
()
or
str
(
test
)
else
:
else
:
self
.
stream
.
write
(
str
(
test
))
return
str
(
test
)
self
.
stream
.
write
(
" ... "
)
def
stopTest
(
self
,
test
):
def
startTest
(
self
,
test
):
TestResult
.
stopTest
(
self
,
test
)
TestResult
.
startTest
(
self
,
test
)
if
self
.
lastFailure
is
not
test
:
if
self
.
showAll
:
self
.
stream
.
write
(
self
.
getDescription
(
test
))
self
.
stream
.
write
(
" ... "
)
def
addSuccess
(
self
,
test
):
TestResult
.
addSuccess
(
self
,
test
)
if
self
.
showAll
:
self
.
stream
.
writeln
(
"ok"
)
self
.
stream
.
writeln
(
"ok"
)
elif
self
.
dots
:
self
.
stream
.
write
(
'.'
)
def
addError
(
self
,
test
,
err
):
def
addError
(
self
,
test
,
err
):
TestResult
.
addError
(
self
,
test
,
err
)
TestResult
.
addError
(
self
,
test
,
err
)
self
.
_printError
(
"ERROR"
,
test
,
err
)
if
self
.
showAll
:
self
.
lastFailure
=
test
self
.
stream
.
writeln
(
"ERROR"
)
elif
self
.
dots
:
self
.
stream
.
write
(
'E'
)
if
err
[
0
]
is
KeyboardInterrupt
:
if
err
[
0
]
is
KeyboardInterrupt
:
self
.
shouldStop
=
1
self
.
shouldStop
=
1
def
addFailure
(
self
,
test
,
err
):
def
addFailure
(
self
,
test
,
err
):
TestResult
.
addFailure
(
self
,
test
,
err
)
TestResult
.
addFailure
(
self
,
test
,
err
)
self
.
_printError
(
"FAIL"
,
test
,
err
)
if
self
.
showAll
:
self
.
lastFailure
=
test
self
.
stream
.
writeln
(
"FAIL"
)
elif
self
.
dots
:
def
_printError
(
self
,
flavour
,
test
,
err
):
self
.
stream
.
write
(
'F'
)
errLines
=
[]
separator1
=
"
\
t
"
+
'='
*
70
def
printErrors
(
self
):
separator2
=
"
\
t
"
+
'-'
*
70
if
self
.
dots
or
self
.
showAll
:
if
not
self
.
lastFailure
is
test
:
self
.
stream
.
writeln
()
self
.
stream
.
writeln
()
self
.
stream
.
writeln
(
separator1
)
self
.
printErrorList
(
'ERROR'
,
self
.
errors
)
self
.
stream
.
writeln
(
"
\
t
%s"
%
flavour
)
self
.
printErrorList
(
'FAIL'
,
self
.
failures
)
self
.
stream
.
writeln
(
separator2
)
for
line
in
apply
(
traceback
.
format_exception
,
err
):
def
printErrorList
(
self
,
flavour
,
errors
):
for
l
in
string
.
split
(
line
,
"
\
n
"
)[:
-
1
]:
for
test
,
err
in
errors
:
self
.
stream
.
writeln
(
"
\
t
%s"
%
l
)
self
.
stream
.
writeln
(
self
.
separator1
)
self
.
stream
.
writeln
(
separator1
)
self
.
stream
.
writeln
(
"%s: %s"
%
(
flavour
,
self
.
getDescription
(
test
)))
self
.
stream
.
writeln
(
self
.
separator2
)
for
line
in
apply
(
traceback
.
format_exception
,
err
):
for
l
in
string
.
split
(
line
,
"
\
n
"
)[:
-
1
]:
self
.
stream
.
writeln
(
"%s"
%
l
)
class
Verbose
TextTestRunner
:
class
TextTestRunner
:
"""A test runner class that displays results in textual form.
"""A test runner class that displays results in textual form.
It prints out the names of tests as they are run, errors as they
It prints out the names of tests as they are run, errors as they
occur, and a summary of the results at the end of the test run.
occur, and a summary of the results at the end of the test run.
"""
"""
def
__init__
(
self
,
stream
=
sys
.
stderr
,
descriptions
=
1
):
def
__init__
(
self
,
stream
=
sys
.
stderr
,
descriptions
=
1
,
verbosity
=
1
):
self
.
stream
=
_WritelnDecorator
(
stream
)
self
.
stream
=
_WritelnDecorator
(
stream
)
self
.
descriptions
=
descriptions
self
.
descriptions
=
descriptions
self
.
verbosity
=
verbosity
def
_makeResult
(
self
):
return
_TextTestResult
(
self
.
stream
,
self
.
descriptions
,
self
.
verbosity
)
def
run
(
self
,
test
):
def
run
(
self
,
test
):
"Run the given test case or test suite."
"Run the given test case or test suite."
result
=
_VerboseTextTestResult
(
self
.
stream
,
self
.
descriptions
)
result
=
self
.
_makeResult
(
)
startTime
=
time
.
time
()
startTime
=
time
.
time
()
test
(
result
)
test
(
result
)
stopTime
=
time
.
time
()
stopTime
=
time
.
time
()
timeTaken
=
float
(
stopTime
-
startTime
)
timeTaken
=
float
(
stopTime
-
startTime
)
self
.
stream
.
writeln
(
"-"
*
78
)
result
.
printErrors
()
self
.
stream
.
writeln
(
result
.
separator2
)
run
=
result
.
testsRun
run
=
result
.
testsRun
self
.
stream
.
writeln
(
"Ran %d test%s in %.3fs"
%
self
.
stream
.
writeln
(
"Ran %d test%s in %.3fs"
%
(
run
,
run
>
1
and
"s"
or
"
"
,
timeTaken
))
(
run
,
run
==
1
and
""
or
"s
"
,
timeTaken
))
self
.
stream
.
writeln
()
self
.
stream
.
writeln
()
if
not
result
.
wasSuccessful
():
if
not
result
.
wasSuccessful
():
self
.
stream
.
write
(
"FAILED ("
)
self
.
stream
.
write
(
"FAILED ("
)
...
@@ -605,9 +589,6 @@ class VerboseTextTestRunner:
...
@@ -605,9 +589,6 @@ class VerboseTextTestRunner:
return
result
return
result
# Which flavour of TextTestRunner is the default?
TextTestRunner
=
VerboseTextTestRunner
##############################################################################
##############################################################################
# Facilities for running tests from the command line
# Facilities for running tests from the command line
...
@@ -618,17 +599,22 @@ class TestProgram:
...
@@ -618,17 +599,22 @@ class TestProgram:
for making test modules conveniently executable.
for making test modules conveniently executable.
"""
"""
USAGE
=
"""
\
USAGE
=
"""
\
Usage: %(progName)s [-h|--help] [test[:(casename|prefix-)]] [...]
Usage: %(progName)s [options] [test[:(casename|prefix-)]] [...]
Options:
-h, --help Show this message
-v, --verbose Verbose output
-q, --quiet Minimal output
Examples:
Examples:
%(progName)s - run default set of tests
%(progName)s - run default set of tests
%(progName)s MyTestSuite - run suite 'MyTestSuite'
%(progName)s MyTestSuite - run suite 'MyTestSuite'
%(progName)s MyTestCase
:checkSomething - run MyTestCase.check
Something
%(progName)s MyTestCase
.testSomething - run MyTestCase.test
Something
%(progName)s MyTestCase
:check- - run all 'check
*' test methods
%(progName)s MyTestCase
- run all 'test
*' test methods
in MyTestCase
in MyTestCase
"""
"""
def
__init__
(
self
,
module
=
'__main__'
,
defaultTest
=
None
,
def
__init__
(
self
,
module
=
'__main__'
,
defaultTest
=
None
,
argv
=
None
,
testRunner
=
None
):
argv
=
None
,
testRunner
=
None
,
testLoader
=
defaultTestLoader
):
if
type
(
module
)
==
type
(
''
):
if
type
(
module
)
==
type
(
''
):
self
.
module
=
__import__
(
module
)
self
.
module
=
__import__
(
module
)
for
part
in
string
.
split
(
module
,
'.'
)[
1
:]:
for
part
in
string
.
split
(
module
,
'.'
)[
1
:]:
...
@@ -637,11 +623,12 @@ Examples:
...
@@ -637,11 +623,12 @@ Examples:
self
.
module
=
module
self
.
module
=
module
if
argv
is
None
:
if
argv
is
None
:
argv
=
sys
.
argv
argv
=
sys
.
argv
self
.
verbosity
=
1
self
.
defaultTest
=
defaultTest
self
.
defaultTest
=
defaultTest
self
.
testRunner
=
testRunner
self
.
testRunner
=
testRunner
self
.
testLoader
=
testLoader
self
.
progName
=
os
.
path
.
basename
(
argv
[
0
])
self
.
progName
=
os
.
path
.
basename
(
argv
[
0
])
self
.
parseArgs
(
argv
)
self
.
parseArgs
(
argv
)
self
.
createTests
()
self
.
runTests
()
self
.
runTests
()
def
usageExit
(
self
,
msg
=
None
):
def
usageExit
(
self
,
msg
=
None
):
...
@@ -652,29 +639,34 @@ Examples:
...
@@ -652,29 +639,34 @@ Examples:
def
parseArgs
(
self
,
argv
):
def
parseArgs
(
self
,
argv
):
import
getopt
import
getopt
try
:
try
:
options
,
args
=
getopt
.
getopt
(
argv
[
1
:],
'hH'
,
[
'help'
])
options
,
args
=
getopt
.
getopt
(
argv
[
1
:],
'hHvq'
,
[
'help'
,
'verbose'
,
'quiet'
])
opts
=
{}
opts
=
{}
for
opt
,
value
in
options
:
for
opt
,
value
in
options
:
if
opt
in
(
'-h'
,
'-H'
,
'--help'
):
if
opt
in
(
'-h'
,
'-H'
,
'--help'
):
self
.
usageExit
()
self
.
usageExit
()
if
opt
in
(
'-q'
,
'--quiet'
):
self
.
verbosity
=
0
if
opt
in
(
'-v'
,
'--verbose'
):
self
.
verbosity
=
2
if
len
(
args
)
==
0
and
self
.
defaultTest
is
None
:
if
len
(
args
)
==
0
and
self
.
defaultTest
is
None
:
raise
getopt
.
error
,
"No default test is defined."
self
.
test
=
self
.
testLoader
.
loadTestsFromModule
(
self
.
module
)
return
if
len
(
args
)
>
0
:
if
len
(
args
)
>
0
:
self
.
testNames
=
args
self
.
testNames
=
args
else
:
else
:
self
.
testNames
=
(
self
.
defaultTest
,)
self
.
testNames
=
(
self
.
defaultTest
,)
self
.
createTests
()
except
getopt
.
error
,
msg
:
except
getopt
.
error
,
msg
:
self
.
usageExit
(
msg
)
self
.
usageExit
(
msg
)
def
createTests
(
self
):
def
createTests
(
self
):
tests
=
[]
self
.
test
=
self
.
testLoader
.
loadTestsFromNames
(
self
.
testNames
,
for
testName
in
self
.
testNames
:
self
.
module
)
tests
.
append
(
createTestInstance
(
testName
,
self
.
module
))
self
.
test
=
TestSuite
(
tests
)
def
runTests
(
self
):
def
runTests
(
self
):
if
self
.
testRunner
is
None
:
if
self
.
testRunner
is
None
:
self
.
testRunner
=
TextTestRunner
()
self
.
testRunner
=
TextTestRunner
(
verbosity
=
self
.
verbosity
)
result
=
self
.
testRunner
.
run
(
self
.
test
)
result
=
self
.
testRunner
.
run
(
self
.
test
)
sys
.
exit
(
not
result
.
wasSuccessful
())
sys
.
exit
(
not
result
.
wasSuccessful
())
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment