File contents
################################################################################
# Copyright (c) 1999,2000 Tres Seaver, Palladion Software
# -------------------------------------------------------
#
# LICENSE
#
# Permission to reproduce and create derivative works from the
# Software ("Software Derivative Works") is hereby granted to you
# under the copyright of Tres Seaver (the Author). The Author also grants
# you the right to distribute the Software and Software Derivative Works.
#
# The Author licenses the Software to you on an "AS IS" basis, without
# warranty of any kind. THE AUTHOR HEREBY EXPRESSLY DISCLAIMS ALL
# WARRANTIES OR CONDITIONS, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT
# NOT LIMITED TO, THE IMPLIED WARRANTIES OR CONDITIONS OF
# MERCHANTABILITY, NON INFRINGEMENT AND FITNESS FOR A PARTICULAR
# PURPOSE. You are solely responsible for determining the
# appropriateness of using the Software and assume all risks
# associated with the use and distribution of this Software, including
# but not limited to the risks of program errors, damage to or loss of
# data, programs or equipment, and unavailability or interruption of
# operations. THE AUTHOR WILL NOT BE LIABLE FOR ANY DIRECT DAMAGES
# OR FOR ANY SPECIAL, INCIDENTAL, OR INDIRECT DAMAGES OR FOR ANY
# ECONOMIC CONSEQUENTIAL DAMAGES (INCLUDING LOST PROFITS OR SAVINGS),
# EVEN IF THE AUTHOR HAD BEEN ADVISED OF THE POSSIBILITY OF SUCH
# DAMAGE. The Author will not be liable for the loss of, or damage
# to, your records or data, or any damages claimed by you based on a
# third party claim.
#
# You agree to distribute the Software and any Software Derivatives
# under a license agreement that: 1) is sufficient to notify all
# licensees of the Software and Software Derivatives that the Author
# assumes no liability for any claim that may arise regarding the
# Software or Software Derivatives, and 2) that disclaims all
# warranties, both express and implied, from the Author regarding the
# Software and Software Derivatives. (If you include this Agreement
# with any distribution of the Software and Software Derivatives you
# will have meet this requirement). You agree that you will not
# delete any copyright notices in the Software.
#
# This Agreement is the exclusive statement of your rights in the
# Software as provided by the Author. Except for the licenses
# granted to you in the second paragraph above, no other licenses are
# granted hereunder, by estoppel, implication or otherwise.
################################################################################
__doc__ = """ Emulate JUnit testing framework."""
__version__="1.0"
import sys
import string
import types
#-------------------------------------------------------------------------------
def abstractMethodCalled():
raise Exception( "abstract method called" )
#-------------------------------------------------------------------------------
def assertValue( got, expected, msg ):
"""
"""
assert expected == got, '%s: expected %s, got %s' % ( msg, expected, got )
#-------------------------------------------------------------------------------
def assertValueDelta( got, expected, delta, msg ):
"""
"""
assert abs( expected - got ) <= delta, \
'%s: expected %s, got %s, delta %s' % ( msg, expected, got, delta )
#-------------------------------------------------------------------------------
class TestResults:
"""
"""
def __init__( self ):
self.testsRun = 0
self.failures = []
self.errors = []
def run( self, testCase ):
try:
self.testsRun = self.testsRun + 1
testCase.fctn()
except AssertionError, ae:
self.failures.append( ( testCase.name, ae ) )
except Exception, e:
self.errors.append( ( testCase.name, e ) )
except:
self.errors.append( ( testCase.name, 'non-Exception object' ) )
def __str__( self ):
lines = []
if self.failures or self.errors:
for failure in self.failures:
lines.append( '[%-30s] failed: %s' % failure )
for error in self.errors:
lines.append( '[%-30s] threw: %s' % error )
else:
lines.append( 'OK' )
return string.join( lines, '\n' )
#-------------------------------------------------------------------------------
class TestCase:
"""
"""
def __init__( self, name, fctn ):
self.name = name
self.fctn = fctn
def __call__( self, result ):
result.run( self )
return result
#-------------------------------------------------------------------------------
class TestSuite:
"""
"""
def __init__( self, name ):
self.name = name
self.children = []
def addChild( self, child ):
self.children.append( child )
def __call__( self, result ):
for child in self.children:
child( result )
return result
#-------------------------------------------------------------------------------
def suiteFromDict( namespace ):
suite = TestSuite( namespace[ '__name__' ] )
for key, value in namespace.items():
if key[:4] == 'test' and type( value ) == types.FunctionType:
suite.addChild( TestCase( key[ 4: ], value ) )
return suite
#-------------------------------------------------------------------------------
def buildTestSuite( target ):
if type( target ) == types.DictionaryType:
return suiteFromDict( target )
elif type( target ) == types.ModuleType:
return buildTestSuite( target.__dict__ )
elif type( target ) == types.StringType:
if globals().has_key( target ):
target = globals()[ target ]
else:
target = __import__( target, globals() )
return buildTestSuite( target )
elif type( target ) == types.ListType or type( target ) == types.TupleType:
suite = TestSuite( '<list>' )
for element in target:
suite.addChild( buildTestSuite( element ) )
return suite
#-------------------------------------------------------------------------------
def runUnitTests( target ):
suite = buildTestSuite( target )
results = TestResults()
return suite( results )
#-------------------------------------------------------------------------------
def exerciseUnitTests():
def doFine():
pass
def doFail():
assert 0, 'asserted 0'
def doExcept():
raise Exception( 'Except' )
def doPuke():
raise 'Puke'
secondary = { '__name__' : 'Secondary namespace'
, 'testFineXX' : doFine
, 'testFailXX' : doFail
, 'testExceptXX' : doExcept
, 'testPukeXX' : doPuke
}
suite = buildTestSuite( secondary )
results = TestResults()
suite( results )
print 'Expecting one fail and two throws:'
print str( results )
assert len( results.failures ) == 1
assert len( results.errors ) == 2
#-------------------------------------------------------------------------------
if __name__ == '__main__':
testUnitTests = exerciseUnitTests
results = runUnitTests( globals() )
print str( results )