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