From: Oti <oh...@ya...> - 2002-04-10 04:43:07
|
[ Dave Dench ] > Dear All, > I have searched the archives and posted on the Junit list. > No definitive answer, so trying again. ;) > I have been using unittest with Jython but would like to use JUnit > for teaching/illustrative purposes. The maillings suggest that use > of JUnit and automatic suite generation is problematical due to reflection. > I have tried using docstrings and jythonc but without much success. > Does there exist a port of the JUnit distribution demo ( Money ) in > jython that successfully works with GUI runner that I can use as a > leg-up ? Hello Dave, below is a very simple, easy to extend Jython embedding into JUnit. Please do not hesitate to ask me if something should not be clear. Best wishes, Oti. Step 1: In junit.<any>ui.TestRunner.java: ========================================= - rename method getTest() to getJavaTest() - rewrite method getTest() as follows: (convention: a suite containing '.' is assumed to be java a suite containing '/' is assumed to be jython) private Test getTest( String suiteClassName ) { // feel free to use your own convention here if ( suiteClassName.indexOf( "." ) >= 0 ) { return getTestOrig( suiteClassName ); } else { if ( _oTestFinder == null ) _oTestFinder = new OTestFinder(); Test result = _oTestFinder.getTest( suiteClassName ); if ( result == null ) { System.out.println( "Problems loading '" + suiteClassName + "'" ); System.exit(1); } return result; } } Step 2: Write OTestFinder.java: =============================== package your.package; import junit.framework.Test; import org.python.core.PyObject; import org.python.core.PySystemState; import org.python.util.PythonInterpreter; /** * Find JUnit tests written in Jython. * The class OTestFinderImpl has to be located in a file named OTestFinderImpl.py, * in a directory named 'UnitTesting' below sys.path. */ public class OTestFinder { private PythonInterpreter _interpreter = null; public OTestFinder() { PySystemState.initialize(); _interpreter = new PythonInterpreter(); _interpreter.exec( "from UnitTesting.OTestFinderImpl import OTestFinderImpl" ); _interpreter.exec( "_finder = OTestFinderImpl()" ); } public Test getTest( String name ) { PyObject pyTest = _interpreter.eval( "_finder.getTest(\"" + name + "\")" ); return (Test) pyTest.__tojava__( Test.class ); } } Step 3: Implement the test finder in Jython (OTestFinderImpl.py): ================================================================= import sys from UnitTesting.PyOTestCase import PyOTestCase sys.add_package( "junit.framework" ) from junit.framework import TestSuite ROOT = "e:/pwe/CH/obj/UnitTesting" class OTestFinderImpl: def __init__( self ): pass def getTest( self, name ): suite = TestSuite() dict = {} # we implement a very simple find strategy here: execfile( "%s/%s.py" % (ROOT, name), dict, dict ) for key, value in dict.items(): if type(value) == type(PyOTestCase) and issubclass( value, PyOTestCase ): methodNames = value.__dict__.keys() methodNames.sort() for methodName in methodNames: if methodName[:4] == "test": suite.addTest( value(name, methodName) ) return suite Step 4: Write the base class PyOTestCase for all tests (PyOTestCase.py) ======================================================================= import sys sys.add_package( "java.lang" ) sys.add_package( "junit.framework" ) from java.lang import System from junit.framework import TestCase class PyOTestCase( TestCase ): def __init__( self, fileName, name ): TestCase.__init__( self, name ) self.__fileName_ = fileName def runTest( self ): self.__startTime_ = System.currentTimeMillis() apply( getattr(self, self.name()), () ) self.__syslog( "Elapsed time %d " % (System.currentTimeMillis() - self.__startTime_, )) def runBare( self ): self.super__runBare() def check( self, condition, message="" ): if not condition: raise AssertionError, message def log( self, str ): print "[%s] %s" % ( self, str ) def __syslog( self, str ): print "[*%s*] %s" % ( self, str ) def __repr__( self ): return "%s.%s (%s)" % ( self.__class__.__name__, self.name(), self.__fileName_ ) def toString( self ): return self.__repr__() Step 5: Write a simple JUnit test (olocalhost.py): ================================================== import sys from UnitTesting.PyOTestCase import PyOTestCase sys.add_package( "java.net" ) from java.net import InetAddress class olocalhostTest( PyOTestCase ): def setUp( self ): self._localIP = "127.0.0.1" def tearDown( self ): self._localIP = None def testLocalhost( self ): effectiveIP = InetAddress.getByName( 'localhost' ).getHostAddress() self.check( effectiveIP == self._localIP, "InetAddress.getByName('localhost') returned IP address %s instead of %s" % \ ( effectiveIP, self._localIP ) ) self.log( "InetAddress.getByName('localhost') returned IP address %s" % effectiveIP ) def testFailure( self ): self.check( 0, "this test is intended to fail" ) Step 6: Run JUnit: ================== [huohead|pwe] > junitopen Libraries/Utility/olocalhost .E.[olocalhostTest.testLocalhost (Libraries/Utility/olocalhost)] InetAddress.getByName('localhost') returned IP address 127.0.0.1 [*olocalhostTest.testLocalhost (Libraries/Utility/olocalhost)*] Elapsed time 10 Time: 0.151 FAILURES!!! Test Results: Run: 2 Failures: 0 Errors: 1 There was 1 error: 1) olocalhostTest.testFailure (Libraries/Utility/olocalhost) Traceback (innermost last): File "e:\pwe\CH\obj\Scripts\UnitTesting\PyOTestCase.py", line 20, in runBare File "e:\pwe\CH\obj\Scripts\UnitTesting\PyOTestCase.py", line 16, in runTest File "e:/pwe/CH/obj/UnitTesting/Libraries/Utility/olocalhost.py", line 23, in testFailure File "e:\pwe\CH\obj\Scripts\UnitTesting\PyOTestCase.py", line 24, in check AssertionError: this test is intended to fail [huohead|pwe] > junitopen is an alias for: java -Dpython.path=e:/pwe/CH/obj/Scripts -Dpython.home=e:/jython21 -classpath your_classpath junit.textui.TestRunner All this also works for junit.ui.TestRunner. __________________________________________________ Do You Yahoo!? Yahoo! Tax Center - online filing with TurboTax http://taxes.yahoo.com/ |
From: Waclawczyk J. <Jan...@ic...> - 2002-04-10 07:35:56
|
Hi, sombody posted the following code some years ago in the jpython-users list. HTH Janusz Waclawczyk ---- from junit.framework import * from junit.framework import TestCase from junit.framework import TestSuite from junit.textui import TestRunner class PyTestCase(TestCase): def __init__(self, name): TestCase.__init__(self, name) def runTest(self): testMethod = getattr(self, self.name()) testMethod() class PyTestSuite(TestSuite): def __init__(self, name): TestSuite.__init__(self,name) class MyRunner(TestRunner): def __init__(self): TestRunner.__init__(self) #FRAMEWORK def runSuite(suite): tr = MyRunner() result = tr.createTestResult() result.addListener(tr) print "running suite %s ..." % suite.toString() suite.run(result); tr.printHeader(result) tr.printErrors(result) tr.printFailures(result) return result.errorCount() + result.failureCount() def runTc(tc): """runTc runs one test case and print the results""" tr = MyRunner() result = tr.createTestResult() result.addListener(tr) suite = TestSuite() suite.addTest(tc) suite.run(result); tr.printHeader(result) tr.printErrors(result) tr.printFailures(result) return result.errorCount() + result.failureCount() 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, suiteName="TestSuite", 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'. """ testFuncs = getTestCaseNames(testCaseClass, prefix, sortUsing) suite = PyTestSuite(suiteName) for name in testFuncs: tc = testCaseClass(name) suite.addTest(tc) #cases = map(testCaseClass, # getTestCaseNames(testCaseClass, prefix, sortUsing)) return suite if __name__ == '__main__': print "JunitTest's main is empty" |