Skip to content

bpo-29642: Load tests from implicit packages. #282

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion Doc/library/unittest.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1674,7 +1674,8 @@ Loading and running tests
the import failure is due to :exc:`SkipTest` being raised, it will be
recorded as a skip instead of an error.

If a package (a directory containing a file named :file:`__init__.py`) is
If a package (a directory containing a file named :file:`__init__.py` or
a :term:`namespace package <namespace package>`) is
found, the package will be checked for a ``load_tests`` function. If this
exists then it will be called
``package.load_tests(loader, tests, pattern)``. Test discovery takes care
Expand Down
10 changes: 1 addition & 9 deletions Lib/unittest/loader.py
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ def discover(self, start_dir, pattern='test*.py', top_level_dir=None):
If the start directory is not the top level directory then the top
level directory must be specified separately.

If a test package name (directory with '__init__.py') matches the
If a test package name (directory with or w/o '__init__.py') matches the
pattern then the package will be checked for a 'load_tests' function. If
this exists then it will be called with (loader, tests, pattern) unless
the package has already had load_tests called from the same discovery
Expand Down Expand Up @@ -282,8 +282,6 @@ def discover(self, start_dir, pattern='test*.py', top_level_dir=None):
tests = []
if os.path.isdir(os.path.abspath(start_dir)):
start_dir = os.path.abspath(start_dir)
if start_dir != top_level_dir:
is_not_importable = not os.path.isfile(os.path.join(start_dir, '__init__.py'))
else:
# support for discovery from dotted module names
try:
Expand Down Expand Up @@ -451,12 +449,6 @@ def _find_test_path(self, full_path, pattern, namespace=False):
msg % (mod_name, module_dir, expected_dir))
return self.loadTestsFromModule(module, pattern=pattern), False
elif os.path.isdir(full_path):
if (not namespace and
not os.path.isfile(os.path.join(full_path, '__init__.py'))):
return None, False

load_tests = None
tests = None
name = self._get_name_from_path(full_path)
try:
package = self._get_module_from_name(name)
Expand Down
6 changes: 3 additions & 3 deletions Lib/unittest/test/test_discovery.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ def restore_isdir():

path_lists = [['test2.py', 'test1.py', 'not_a_test.py', 'test_dir',
'test.foo', 'test-not-a-module.py', 'another_dir'],
['test4.py', 'test3.py', ]]
[], ['test4.py', 'test3.py']]
os.listdir = lambda path: path_lists.pop(0)
self.addCleanup(restore_listdir)

Expand All @@ -65,7 +65,7 @@ def isdir(path):

def isfile(path):
# another_dir is not a package and so shouldn't be recursed into
return not path.endswith('dir') and not 'another_dir' in path
return not path.endswith('dir') and 'another_dir' not in path
os.path.isfile = isfile
self.addCleanup(restore_isfile)

Expand All @@ -85,7 +85,7 @@ def loadTestsFromModule(module, pattern=None):
# The test suites found should be sorted alphabetically for reliable
# execution order.
expected = [[name + ' module tests'] for name in
('test1', 'test2', 'test_dir')]
('another_dir', 'test1', 'test2', 'test_dir')]
expected.extend([[('test_dir.%s' % name) + ' module tests'] for name in
('test3', 'test4')])
self.assertEqual(suite, expected)
Expand Down