Rev 2472: Refactor out recursiveLoadTests into helper functions. in http://bzr.arbash-meinel.com/branches/bzr/0.17-dev/test_autoloader
John Arbash Meinel
john at arbash-meinel.com
Fri Apr 27 23:07:48 BST 2007
At http://bzr.arbash-meinel.com/branches/bzr/0.17-dev/test_autoloader
------------------------------------------------------------
revno: 2472
revision-id: john at arbash-meinel.com-20070427220730-cr3k1aevdflppbar
parent: john at arbash-meinel.com-20070427211920-5u7sa7e8q1q7wy2z
committer: John Arbash Meinel <john at arbash-meinel.com>
branch nick: test_autoloader
timestamp: Fri 2007-04-27 17:07:30 -0500
message:
Refactor out recursiveLoadTests into helper functions.
modified:
bzrlib/tests/TestUtil.py TestUtil.py-20050824080200-5f70140a2d938694
bzrlib/tests/test_test_util.py test_test_util.py-20070427203042-9m1ldokoqp9hsdwg-1
-------------- next part --------------
=== modified file 'bzrlib/tests/TestUtil.py'
--- a/bzrlib/tests/TestUtil.py 2007-04-27 20:31:12 +0000
+++ b/bzrlib/tests/TestUtil.py 2007-04-27 22:07:30 +0000
@@ -92,10 +92,10 @@
return result
@staticmethod
- def find_test_files(base):
+ def findTestFiles(base):
"""Find test files for all files underneath a given directory.
- :param base: A base directory to look for files and subdirs.
+ :param path: A base directory to look for files and subdirs.
:return: ([test_files], [packages]) A list of test files and python
packages (dirs with __init__.py) that should contain tests.
"""
@@ -111,17 +111,63 @@
else:
if name.startswith('test') and name.endswith('.py'):
names.append(name)
- return names, packages
-
- def recursiveLoadTests(self, base, python_base):
- """Load all test cases that are underneath base.
-
- Any test_*.py files in the base directory will be loaded directly. For
+ return sorted(names), sorted(packages)
+
+ def findTestModules(self, path, python_prefix):
+ """Find all of the test modules in a given directory.
+
+ :param path: The directory to look in
+ :param python_prefix: The python path to that directory.
+ :return: (modules, packages)
+ Lists of all python modules which match test*.py
+ and any packages.
+
+ Example:
+ This will give you all of the test*.py modules in the same
+ directory as the current module. Useful for packages to load
+ all of their tests.
+ modules = TestLoader.findTestModules(dirname(__file__), __name__)
+ """
+ names, packages = self.findTestFiles(path)
+ modules = []
+ for name in names:
+ assert name.endswith('.py')
+ full_python_name = python_prefix + '.' + name[:-3]
+ modules.append(full_python_name)
+ python_packages = []
+ for package in packages:
+ full_python_name = python_prefix + '.' + package
+ python_packages.append(full_python_name)
+ return modules, python_packages
+
+ def loadFromPackageNames(self, packages):
+ """Load Test Cases from a list of packages.
+
+ This imports the packages and then loads a test suite from a function
+ called 'test_suite()'.
+ If 'test_suite()' is not available, no error is raised, and the package
+ is just skipped.
+
+ :param packages: A list of python package names.
+ :return: An aggregated test suite.
+ """
+ suite = self.suiteClass()
+ for package in packages:
+ pkg = __import__(package, {}, {}, ['test_suite'])
+ test_suite = getattr(pkg, 'test_suite', None)
+ if test_suite is not None:
+ suite.addTests(test_suite())
+ return suite
+
+ def recursiveLoadTests(self, path, python_prefix):
+ """Load all test cases that are underneath path.
+
+ Any test_*.py files in the path directory will be loaded directly. For
python packages, they will be loaded and package.test_suite() will be
run to get a TestSuite that should be run.
- :param base: The base directory to start looking.
- :param python_base: The python name matching the base directory.
+ :param path: The directory to look in.
+ :param python_prefix: The python name matching path.
:return: a TestSuite() with all the tests loaded.
Example:
@@ -129,19 +175,9 @@
cur_dir = os.path.basename(__file__)
loader.recursiveLoadTests(cur_dir, __name__)
"""
- names, packages = self.find_test_files(base)
- modules = []
- for name in names:
- assert name.endswith('.py')
- full_python_name = python_base + '.' + name[:-3]
- modules.append(full_python_name)
+ modules, packages = self.findTestModules(path, python_prefix)
suite = self.loadTestsFromNames(modules)
- for package in packages:
- pkg_name = python_base + '.' + package
- pkg = __import__(pkg_name, {}, {}, ['test_suite'])
- test_suite = getattr(pkg, 'test_suite', None)
- if test_suite is not None:
- suite.addTests(test_suite())
+ suite.addTests(self.loadFromPackageNames(packages))
return suite
=== modified file 'bzrlib/tests/test_test_util.py'
--- a/bzrlib/tests/test_test_util.py 2007-04-27 20:31:12 +0000
+++ b/bzrlib/tests/test_test_util.py 2007-04-27 22:07:30 +0000
@@ -30,7 +30,7 @@
def assertFindTestFiles(self, files, packages, path):
self.assertEqual((files, packages),
- tests.TestLoader.find_test_files(path))
+ tests.TestLoader.findTestFiles(path))
def test_none(self):
self.assertFindTestFiles([], [], '.')
@@ -39,6 +39,10 @@
self.build_tree(['test_foo.py'])
self.assertFindTestFiles(['test_foo.py'], [], '.')
+ def test_multiple(self):
+ self.build_tree(['test_foo.py', 'bar.py', 'test_baz.py'])
+ self.assertFindTestFiles(['test_baz.py', 'test_foo.py'], [], '.')
+
def test_non_package_dir(self):
"""Only consider it a package if there is an __init__.py"""
self.build_tree(['bar/', 'bar/foo', 'bar/baz.py'])
@@ -55,6 +59,115 @@
self.assertFindTestFiles(['test_baz.py'], ['foo'], 'bar')
+class TestFindTestModules(tests.TestCaseInTempDir):
+ """Test that we can find all the test modules in a given dir."""
+
+ def assertFindTestModules(self, modules, packages, path, python_prefix):
+ """Check the return value of TestLoader.findTestModules.
+
+ :param modules: The list of expected modules.
+ :param packages: The list of expected packages.
+ :param path: The path to search.
+ :param python_prefix: The python prefix to add to each module.
+ """
+ loader = tests.TestLoader()
+ self.assertEqual((modules, packages),
+ loader.findTestModules(path, python_prefix))
+
+ def test_none(self):
+ self.assertFindTestModules([], [], '.', 'foo')
+
+ def test_one(self):
+ self.build_tree(['test_foo.py'])
+ self.assertFindTestModules(['foo.test_foo'], [], '.', 'foo')
+
+ def test_non_package_dir(self):
+ """Only consider it a package if there is an __init__.py"""
+ self.build_tree(['bar/', 'bar/foo', 'bar/baz.py'])
+ self.assertFindTestModules([], [], '.', 'foo')
+
+ def test_package(self):
+ self.build_tree(['bar/', 'bar/__init__.py'])
+ self.assertFindTestModules([], ['foo.bar'], '.', 'foo')
+
+ def test_subdir(self):
+ self.build_tree(['bar/', 'bar/test_baz.py', 'bar/foo/',
+ 'bar/foo/__init__.py'
+ ])
+ self.assertFindTestModules(['bar.test_baz'], ['bar.foo'], 'bar', 'bar')
+
+
+class TestLoadFromPackageNames(tests.TestCaseInTempDir):
+
+ def assertLoadFromPackageNames(self, expected_tests, packages):
+ """Check that TestLoader finds the right test cases.
+
+ :param expected_tests: A list of expected test names
+ :param packages: A list of python package names.
+
+ The local working directory will be added to sys.path, and then removed
+ at the end. Also sys.modules will be cleared of any newly imported
+ modules.
+ """
+ cwd = os.getcwd()
+ sys.path.insert(0, cwd)
+ module_keys = set(sys.modules.keys())
+ try:
+ loader = tests.TestLoader()
+ suite = loader.loadFromPackageNames(packages)
+ self.assertIsInstance(suite, tests.TestSuite)
+ self.assertEqual(expected_tests,
+ [t.id() for t in tests.iter_suite_tests(suite)])
+ finally:
+ sys.path.remove(cwd)
+ new_keys = set(sys.modules.keys())
+ for mod in new_keys - module_keys:
+ del sys.modules[mod]
+
+ def test_no_package(self):
+ loader = tests.TestLoader()
+ self.assertRaises(ImportError, loader.loadFromPackageNames,
+ ['no_such.package.name'])
+
+ def test_no_test_suite(self):
+ self.build_tree(['loader_test/', 'loader_test/package/'])
+ self.build_tree_contents([
+ ('loader_test/__init__.py', ''),
+ ('loader_test/package/__init__.py',
+ 'import unittest\n'
+ 'class TestFoo(unittest.TestCase):\n'
+ ' def test_one(self):\n'
+ ' pass\n'
+ 'class TestBar(unittest.TestCase):\n'
+ ' def test_two(self):\n'
+ ' pass\n'
+ '\n'
+ ),
+ ])
+ self.assertLoadFromPackageNames([], ['loader_test.package'])
+
+ def test_simple(self):
+ self.build_tree(['loader_test/', 'loader_test/package/'])
+ self.build_tree_contents([
+ ('loader_test/__init__.py', ''),
+ ('loader_test/package/__init__.py',
+ 'import unittest\n'
+ 'class TestFoo(unittest.TestCase):\n'
+ ' def test_one(self):\n'
+ ' pass\n'
+ 'class TestBar(unittest.TestCase):\n'
+ ' def test_two(self):\n'
+ ' pass\n'
+ '\n'
+ 'def test_suite():\n'
+ ' loader = unittest.TestLoader()\n'
+ ' return loader.loadTestsFromTestCase(TestBar)\n'
+ ),
+ ])
+ self.assertLoadFromPackageNames(
+ ['loader_test.package.TestBar.test_two'], ['loader_test.package'])
+
+
class TestRecursiveLoadTests(tests.TestCaseInTempDir):
def assertRecursiveLoadTests(self, expected_tests, path):
More information about the bazaar-commits
mailing list