You are not logged in Log in Join
You are here: Home » Members » Tres Seaver's Zope.org Site » Python Unit Testing Framework » UnitTests.py » View File

Log in
Name

Password

 

UnitTests.py

File details
Size
7 K
File type
text/plain

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 )