I wrote a small script (got some ideas from reportlab) that recurses the whole test folder and collects all classes which extend unittest.TestCase. They are automatically added to a large testsuite. The advantage is that the TestCase class does not need to create a suite itself, and can be as sinle as this. All methods which start with "test" are considered as testing methods.
import unittest
class TestHello(unittest.TestCase):
def testHello(self):
assert 1 == 1
A pattern can be used to tell the script which files to take into account as testCase candidates.
import os
import sys
import fnmatch
import unittest
import traceback
import types
def getTestCaseClasses(module):
"""
Returns all TestCase classes in a module.
"""
testCases = []
def isClass(object):
"""Return true if the object is a class.
Class objects provide these attributes:
__doc__ documentation string
__module__ name of module in which this class was defined
"""
return type(object) is types.ClassType or hasattr(object, '__bases__')
for name in dir(module):
obj = getattr(module, name)
if isClass(obj):
if unittest.TestCase in obj.__bases__:
testCases.append(obj)
return testCases
def getTestSuite(folder, exclude=None, nonImportable=None, pattern='test_*.py'):
"""
Build a test suite of all available test files.
Recurses into the subfilders
"""
if exclude is None:
exclude = []
if nonImportable is None:
nonImportable = []
allTests = unittest.TestSuite()
if os.path.isdir(folder):
sys.path.insert(0, folder)
for root, dirs, filenames in os.walk('.'):
filenames = fnmatch.filter(filenames, pattern)
for filename in filenames:
modname = os.path.splitext(os.path.basename(filename))[0]
if modname not in exclude:
try:
packagePath = root.split(os.sep) + [modname]
modname = '.'.join([p for p in packagePath if p !='.'])
exec 'import %s as module' % modname
testCaseClasses = getTestCaseClasses(module)
for tcc in testCaseClasses:
suite = unittest.makeSuite(tcc, 'test')
allTests.addTest(suite)
except:
tt, tv, tb = sys.exc_info()[:]
nonImportable.append((filename,traceback.format_exception(tt,tv,tb)))
del tt,tv,tb
del sys.path[0]
return allTests
def main(pattern='test_*.py'):
try:
folder = os.path.dirname(__file__)
except:
folder = os.path.dirname(sys.argv[0]) or os.getcwd()
nonImportable = []
testSuite = getTestSuite(folder, nonImportable=nonImportable, pattern=pattern)
unittest.TextTestRunner(verbosity=2).run(testSuite)
if nonImportable:
print '\n#########################################'
print 'the following tests could not be imported'
print '##########################################\n'
for f,tb in nonImportable:
print 'file: "%s"\n%s\n' % (f,''.join([' '+l for l in tb]))
if __name__ == '__main__':
main()
No comments:
Post a Comment