Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Z
Zope
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
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
Zope
Commits
7eccb31a
Commit
7eccb31a
authored
Aug 06, 2001
by
Evan Simpson
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add README.txt docs, remove obsolete unittest.py
parent
e867a6ab
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
30 additions
and
723 deletions
+30
-723
lib/python/Testing/README.txt
lib/python/Testing/README.txt
+30
-0
lib/python/Testing/unittest.py
lib/python/Testing/unittest.py
+0
-723
No files found.
lib/python/Testing/README.txt
0 → 100644
View file @
7eccb31a
The Testing package is a set of shared routines for the Zope unit
testing framework. To add a test suite to a Zope package:
1. Make a 'tests' subdirectory.
2. Copy 'framework.py' into 'tests' from any other package's 'tests'.
Once a test suite has been set up, you can add test modules:
1. Create a file with a name matching 'test*.py'.
2. Define one or more subclasses of 'unittest.TestCase'. The unittest
module is imported by the framework.
3. Define methods for the test classes. Each method's name must start
with 'test'. It should test one small case, using a Python
'assert' statement. Here's a minimal example:
class testClass1(unittest.TestCase):
def testAddition(self):
assert 1 + 1 == 2, 'Addition failed!'
4. You can add 'setUp' and 'tearDown' methods that are automatically
called at the start and end of the test suite.
5. Follow the instructions in 'framework.py' about adding lines to the
top and bottom of the file.
Now you can run the test as "python path/to/tests/testName.py", or
simply go to the 'tests' directory and type "python testName.py".
lib/python/Testing/unittest.py
deleted
100755 → 0
View file @
e867a6ab
#!/usr/bin/env python
"""
Python unit testing framework, based on Erich Gamma's JUnit and Kent Beck's
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
specific test cases and suites (TestCase, TestSuite etc.), and also a
text-based utility class for running the tests and reporting the results
(TextTestRunner).
Copyright (c) 1999, 2000, 2001 Steve Purcell
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
and disclaimer are retained in their original form.
IN NO EVENT SHALL THE AUTHOR BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF
THIS CODE, EVEN IF THE AUTHOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.
THE AUTHOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE. THE CODE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS,
AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
"""
__author__
=
"Steve Purcell"
__email__
=
"stephen_purcell@yahoo.com"
__version__
=
"$Revision: 1.2 $"
[
11
:
-
2
]
import
time
import
sys
import
traceback
import
string
import
os
##############################################################################
# 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
##############################################################################
class
TestResult
:
"""Holder for test result information.
Test results are automatically managed by the TestCase and TestSuite
classes, and do not need to be explicitly manipulated by writers of tests.
Each instance holds the total number of tests run, and collections of
failures and errors that occurred among those test runs. The collections
contain tuples of (testcase, exceptioninfo), where exceptioninfo is a
tuple of values as returned by sys.exc_info().
"""
def
__init__
(
self
,
args
=
(),
kw
=
{}):
self
.
failures
=
[]
self
.
errors
=
[]
self
.
testsRun
=
0
self
.
shouldStop
=
0
self
.
__args
=
args
self
.
__kw
=
kw
def
startTest
(
self
,
test
):
"Called when the given test is about to be run"
self
.
testsRun
=
self
.
testsRun
+
1
def
stopTest
(
self
,
test
):
"Called when the given test has been run"
pass
def
addError
(
self
,
test
,
err
):
"Called when an error has occurred"
self
.
errors
.
append
((
test
,
err
))
def
addFailure
(
self
,
test
,
err
):
"Called when a failure has occurred"
self
.
failures
.
append
((
test
,
err
))
def
wasSuccessful
(
self
):
"Tells whether or not this result was a success"
return
len
(
self
.
failures
)
==
len
(
self
.
errors
)
==
0
def
stop
(
self
):
"Indicates that the tests should be aborted"
self
.
shouldStop
=
1
def
__repr__
(
self
):
return
"<%s run=%i errors=%i failures=%i>"
%
\
(
self
.
__class__
,
self
.
testsRun
,
len
(
self
.
errors
),
len
(
self
.
failures
))
class
TestCase
:
"""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
'runTest'.
If the fixture may be used for many test cases, create as
many test methods as are needed. When instantiating such a TestCase
subclass, specify in the constructor arguments the name of the test method
that the instance is to execute.
If it is necessary to override the __init__ method, the base class
__init__ method must always be called.
"""
def
__init__
(
self
,
methodName
=
'runTest'
,
*
args
,
**
kw
):
"""Create an instance of the class that will use the named test
method when executed. Raises a ValueError if the instance does
not have a method with the specified name.
"""
try
:
self
.
__testMethodName
=
methodName
testMethod
=
getattr
(
self
,
methodName
)
self
.
__testMethodDoc
=
testMethod
.
__doc__
except
AttributeError
:
raise
ValueError
,
"no such test method in %s: %s"
%
\
(
self
.
__class__
,
methodName
)
self
.
__args
=
args
self
.
__kw
=
kw
def
setUp
(
self
):
"Hook method for setting up the test fixture before exercising it."
pass
def
tearDown
(
self
):
"Hook method for deconstructing the test fixture after testing it."
pass
def
countTestCases
(
self
):
return
1
def
defaultTestResult
(
self
):
return
TestResult
(
self
.
__args
,
self
.
__kw
)
def
shortDescription
(
self
):
"""Returns a one-line description of the test, or None if no
description has been provided.
The default implementation of this method returns the first line of
the specified test method's docstring.
"""
doc
=
self
.
__testMethodDoc
return
doc
and
string
.
strip
(
string
.
split
(
doc
,
"
\
n
"
)[
0
])
or
None
def
id
(
self
):
return
"%s.%s"
%
(
self
.
__class__
,
self
.
__testMethodName
)
def
__str__
(
self
):
return
"%s (%s)"
%
(
self
.
__testMethodName
,
self
.
__class__
)
def
__repr__
(
self
):
return
"<%s testMethod=%s>"
%
\
(
self
.
__class__
,
self
.
__testMethodName
)
def
run
(
self
,
result
=
None
):
return
self
(
result
)
def
__call__
(
self
,
result
=
None
):
if
result
is
None
:
result
=
self
.
defaultTestResult
()
result
.
startTest
(
self
)
testMethod
=
getattr
(
self
,
self
.
__testMethodName
)
try
:
try
:
self
.
setUp
()
except
:
result
.
addError
(
self
,
self
.
__exc_info
())
return
try
:
apply
(
testMethod
,
self
.
__args
,
self
.
__kw
)
except
AssertionError
,
e
:
result
.
addFailure
(
self
,
self
.
__exc_info
())
except
:
result
.
addError
(
self
,
self
.
__exc_info
())
try
:
self
.
tearDown
()
except
:
result
.
addError
(
self
,
self
.
__exc_info
())
finally
:
result
.
stopTest
(
self
)
def
debug
(
self
):
"""Run the test without collecting errors in a TestResult"""
self
.
setUp
()
getattr
(
self
,
self
.
__testMethodName
)()
self
.
tearDown
()
def
assert_
(
self
,
expr
,
msg
=
None
):
"""Equivalent of built-in 'assert', but is not optimised out when
__debug__ is false.
"""
if
not
expr
:
raise
AssertionError
,
msg
failUnless
=
assert_
def
failIf
(
self
,
expr
,
msg
=
None
):
"Fail the test if the expression is true."
apply
(
self
.
assert_
,(
not
expr
,
msg
))
def
assertRaises
(
self
,
excClass
,
callableObj
,
*
args
,
**
kwargs
):
"""Assert that an exception of class excClass is thrown
by callableObj when invoked with arguments args and keyword
arguments kwargs. If a different type of exception is
thrown, it will not be caught, and the test case will be
deemed to have suffered an error, exactly as for an
unexpected exception.
"""
try
:
apply
(
callableObj
,
args
,
kwargs
)
except
excClass
:
return
else
:
if
hasattr
(
excClass
,
'__name__'
):
excName
=
excClass
.
__name__
else
:
excName
=
str
(
excClass
)
raise
AssertionError
,
excName
def
assertEqual
(
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
fail
(
self
,
msg
=
None
):
"""Fail immediately, with the given message."""
raise
AssertionError
,
msg
def
__exc_info
(
self
):
"""Return a version of sys.exc_info() with the traceback frame
minimised; usually the top level of the traceback frame is not
needed.
"""
exctype
,
excvalue
,
tb
=
sys
.
exc_info
()
newtb
=
tb
.
tb_next
if
newtb
is
None
:
return
(
exctype
,
excvalue
,
tb
)
return
(
exctype
,
excvalue
,
newtb
)
class
TestSuite
:
"""A test suite is a composite test consisting of a number of TestCases.
For use, create an instance of TestSuite, then add test case instances.
When all tests have been added, the suite can be passed to a test
runner, such as TextTestRunner. It will run the individual test cases
in the order in which they were added, aggregating the results. When
subclassing, do not forget to call the base class constructor.
"""
def
__init__
(
self
,
tests
=
()):
self
.
_tests
=
[]
self
.
addTests
(
tests
)
def
__repr__
(
self
):
return
"<%s tests=%s>"
%
(
self
.
__class__
,
self
.
_tests
)
__str__
=
__repr__
def
countTestCases
(
self
):
cases
=
0
for
test
in
self
.
_tests
:
cases
=
cases
+
test
.
countTestCases
()
return
cases
def
addTest
(
self
,
test
):
self
.
_tests
.
append
(
test
)
def
addTests
(
self
,
tests
):
for
test
in
tests
:
self
.
addTest
(
test
)
def
run
(
self
,
result
):
return
self
(
result
)
def
__call__
(
self
,
result
):
for
test
in
self
.
_tests
:
if
result
.
shouldStop
:
break
test
(
result
)
return
result
def
debug
(
self
):
"""Run the tests without collecting errors in a TestResult"""
for
test
in
self
.
_tests
:
test
.
debug
()
class
FunctionTestCase
(
TestCase
):
"""A test case that wraps a test function.
This is useful for slipping pre-existing test functions into the
PyUnit framework. Optionally, set-up and tidy-up functions can be
supplied. As with TestCase, the tidy-up ('tearDown') function will
always be called if the set-up ('setUp') function ran successfully.
"""
def
__init__
(
self
,
testFunc
,
setUp
=
None
,
tearDown
=
None
,
description
=
None
):
TestCase
.
__init__
(
self
)
self
.
__setUpFunc
=
setUp
self
.
__tearDownFunc
=
tearDown
self
.
__testFunc
=
testFunc
self
.
__description
=
description
def
setUp
(
self
):
if
self
.
__setUpFunc
is
not
None
:
self
.
__setUpFunc
()
def
tearDown
(
self
):
if
self
.
__tearDownFunc
is
not
None
:
self
.
__tearDownFunc
()
def
runTest
(
self
):
self
.
__testFunc
()
def
id
(
self
):
return
self
.
__testFunc
.
__name__
def
__str__
(
self
):
return
"%s (%s)"
%
(
self
.
__class__
,
self
.
__testFunc
.
__name__
)
def
__repr__
(
self
):
return
"<%s testFunc=%s>"
%
(
self
.
__class__
,
self
.
__testFunc
)
def
shortDescription
(
self
):
if
self
.
__description
is
not
None
:
return
self
.
__description
doc
=
self
.
__testFunc
.
__doc__
return
doc
and
string
.
strip
(
string
.
split
(
doc
,
"
\
n
"
)[
0
])
or
None
##############################################################################
# Convenience functions
##############################################################################
def
getTestCaseNames
(
testCaseClass
,
prefix
,
sortUsing
=
cmp
):
"""Extracts all the names of functions in the given test case class
and its base classes that start with the given prefix. This is used
by makeSuite().
"""
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
,
suiteClass
=
TestSuite
):
"""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
,
getTestCaseNames
(
testCaseClass
,
prefix
,
sortUsing
))
return
suiteClass
(
cases
)
def
findTestCases
(
module
,
prefix
=
'test'
,
sortUsing
=
cmp
,
suiteClass
=
TestSuite
):
import
types
tests
=
[]
for
name
in
dir
(
module
):
obj
=
getattr
(
module
,
name
)
if
type
(
obj
)
==
types
.
ClassType
and
issubclass
(
obj
,
TestCase
):
tests
.
append
(
makeSuite
(
obj
,
prefix
=
prefix
,
sortUsing
=
sortUsing
,
suiteClass
=
suiteClass
))
return
suiteClass
(
tests
)
def
createTestInstance
(
name
,
module
=
None
,
suiteClass
=
TestSuite
):
"""Finds tests by their name, optionally only within the given module.
Return the newly-constructed test, ready to run. If the name contains a ':'
then the portion of the name after the colon is used to find a specific
test case within the test case class named before the colon.
Examples:
findTest('examples.listtests.suite')
-- returns result of calling 'suite'
findTest('examples.listtests.ListTestCase:checkAppend')
-- returns result of calling ListTestCase('checkAppend')
findTest('examples.listtests.ListTestCase:check-')
-- returns result of calling makeSuite(ListTestCase, prefix="check")
"""
spec
=
string
.
split
(
name
,
':'
)
if
len
(
spec
)
>
2
:
raise
ValueError
,
"illegal test name: %s"
%
name
if
len
(
spec
)
==
1
:
testName
=
spec
[
0
]
caseName
=
None
else
:
testName
,
caseName
=
spec
parts
=
string
.
split
(
testName
,
'.'
)
if
module
is
None
:
if
len
(
parts
)
<
2
:
raise
ValueError
,
"incomplete test name: %s"
%
name
constructor
=
__import__
(
string
.
join
(
parts
[:
-
1
],
'.'
))
parts
=
parts
[
1
:]
else
:
constructor
=
module
for
part
in
parts
:
constructor
=
getattr
(
constructor
,
part
)
if
not
callable
(
constructor
):
raise
ValueError
,
"%s is not a callable object"
%
constructor
if
caseName
:
if
caseName
[
-
1
]
==
'-'
:
prefix
=
caseName
[:
-
1
]
if
not
prefix
:
raise
ValueError
,
"prefix too short: %s"
%
name
test
=
makeSuite
(
constructor
,
prefix
=
prefix
,
suiteClass
=
suiteClass
)
else
:
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
##############################################################################
# Text UI
##############################################################################
class
_WritelnDecorator
:
"""Used to decorate file-like objects with a handy 'writeln' method"""
def
__init__
(
self
,
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
):
return
getattr
(
self
.
stream
,
attr
)
def
writeln
(
self
,
*
args
):
if
args
:
apply
(
self
.
write
,
args
)
self
.
write
(
self
.
linesep
)
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
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.
Used by VerboseTextTestRunner.
"""
def
__init__
(
self
,
stream
,
descriptions
):
TestResult
.
__init__
(
self
)
self
.
stream
=
stream
self
.
lastFailure
=
None
self
.
descriptions
=
descriptions
def
startTest
(
self
,
test
):
TestResult
.
startTest
(
self
,
test
)
if
self
.
descriptions
:
self
.
stream
.
write
(
test
.
shortDescription
()
or
str
(
test
))
else
:
self
.
stream
.
write
(
str
(
test
))
self
.
stream
.
write
(
" ... "
)
def
stopTest
(
self
,
test
):
TestResult
.
stopTest
(
self
,
test
)
if
self
.
lastFailure
is
not
test
:
self
.
stream
.
writeln
(
"ok"
)
def
addError
(
self
,
test
,
err
):
TestResult
.
addError
(
self
,
test
,
err
)
self
.
_printError
(
"ERROR"
,
test
,
err
)
self
.
lastFailure
=
test
if
err
[
0
]
is
KeyboardInterrupt
:
self
.
shouldStop
=
1
def
addFailure
(
self
,
test
,
err
):
TestResult
.
addFailure
(
self
,
test
,
err
)
self
.
_printError
(
"FAIL"
,
test
,
err
)
self
.
lastFailure
=
test
def
_printError
(
self
,
flavour
,
test
,
err
):
errLines
=
[]
separator1
=
"
\
t
"
+
'='
*
70
separator2
=
"
\
t
"
+
'-'
*
70
if
not
self
.
lastFailure
is
test
:
self
.
stream
.
writeln
()
self
.
stream
.
writeln
(
separator1
)
self
.
stream
.
writeln
(
"
\
t
%s"
%
flavour
)
self
.
stream
.
writeln
(
separator2
)
for
line
in
apply
(
traceback
.
format_exception
,
err
):
for
l
in
string
.
split
(
line
,
"
\
n
"
)[:
-
1
]:
self
.
stream
.
writeln
(
"
\
t
%s"
%
l
)
self
.
stream
.
writeln
(
separator1
)
class
VerboseTextTestRunner
:
"""A test runner class that displays results in textual form.
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.
"""
def
__init__
(
self
,
stream
=
sys
.
stderr
,
descriptions
=
1
):
self
.
stream
=
_WritelnDecorator
(
stream
)
self
.
descriptions
=
descriptions
def
run
(
self
,
test
):
"Run the given test case or test suite."
result
=
_VerboseTextTestResult
(
self
.
stream
,
self
.
descriptions
)
startTime
=
time
.
time
()
test
(
result
)
stopTime
=
time
.
time
()
timeTaken
=
float
(
stopTime
-
startTime
)
self
.
stream
.
writeln
(
"-"
*
78
)
run
=
result
.
testsRun
self
.
stream
.
writeln
(
"Ran %d test%s in %.3fs"
%
(
run
,
run
>
1
and
"s"
or
""
,
timeTaken
))
self
.
stream
.
writeln
()
if
not
result
.
wasSuccessful
():
self
.
stream
.
write
(
"FAILED ("
)
failed
,
errored
=
map
(
len
,
(
result
.
failures
,
result
.
errors
))
if
failed
:
self
.
stream
.
write
(
"failures=%d"
%
failed
)
if
errored
:
if
failed
:
self
.
stream
.
write
(
", "
)
self
.
stream
.
write
(
"errors=%d"
%
errored
)
self
.
stream
.
writeln
(
")"
)
else
:
self
.
stream
.
writeln
(
"OK"
)
return
result
# Which flavour of TextTestRunner is the default?
TextTestRunner
=
VerboseTextTestRunner
##############################################################################
# Facilities for running tests from the command line
##############################################################################
class
TestProgram
:
"""A command-line program that runs a set of tests; this is primarily
for making test modules conveniently executable.
"""
USAGE
=
"""
\
Usage: %(progName)s [-h|--help] [test[:(casename|prefix-)]] [...]
Examples:
%(progName)s - run default set of tests
%(progName)s MyTestSuite - run suite 'MyTestSuite'
%(progName)s MyTestCase:checkSomething - run MyTestCase.checkSomething
%(progName)s MyTestCase:check- - run all 'check*' test methods
in MyTestCase
"""
def
__init__
(
self
,
module
=
'__main__'
,
defaultTest
=
None
,
argv
=
None
,
testRunner
=
None
,
suiteClass
=
TestSuite
):
if
type
(
module
)
==
type
(
''
):
self
.
module
=
__import__
(
module
)
for
part
in
string
.
split
(
module
,
'.'
)[
1
:]:
self
.
module
=
getattr
(
self
.
module
,
part
)
else
:
self
.
module
=
module
if
argv
is
None
:
argv
=
sys
.
argv
self
.
defaultTest
=
defaultTest
self
.
testRunner
=
testRunner
self
.
suiteClass
=
suiteClass
self
.
progName
=
os
.
path
.
basename
(
argv
[
0
])
self
.
parseArgs
(
argv
)
self
.
runTests
()
def
usageExit
(
self
,
msg
=
None
):
if
msg
:
print
msg
print
self
.
USAGE
%
self
.
__dict__
sys
.
exit
(
2
)
def
parseArgs
(
self
,
argv
):
import
getopt
try
:
options
,
args
=
getopt
.
getopt
(
argv
[
1
:],
'hH'
,
[
'help'
])
opts
=
{}
for
opt
,
value
in
options
:
if
opt
in
(
'-h'
,
'-H'
,
'--help'
):
self
.
usageExit
()
if
len
(
args
)
==
0
and
self
.
defaultTest
is
None
:
self
.
test
=
findTestCases
(
self
.
module
,
suiteClass
=
self
.
suiteClass
)
return
if
len
(
args
)
>
0
:
self
.
testNames
=
args
else
:
self
.
testNames
=
(
self
.
defaultTest
,)
self
.
createTests
()
except
getopt
.
error
,
msg
:
self
.
usageExit
(
msg
)
def
createTests
(
self
):
tests
=
[]
for
testName
in
self
.
testNames
:
tests
.
append
(
createTestInstance
(
testName
,
self
.
module
,
suiteClass
=
self
.
suiteClass
))
self
.
test
=
self
.
suiteClass
(
tests
)
def
runTests
(
self
):
if
self
.
testRunner
is
None
:
self
.
testRunner
=
TextTestRunner
()
result
=
self
.
testRunner
.
run
(
self
.
test
)
sys
.
exit
(
not
result
.
wasSuccessful
())
main
=
TestProgram
##############################################################################
# Executing this module from the command line
##############################################################################
if
__name__
==
"__main__"
:
main
(
module
=
None
)
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