Fixed #21206 -- No longer run discovery if the test label doesn't point to a package or directory.

Thanks thepapermen for the report and Carl Meyer for the review.
This commit is contained in:
Preston Timmons 2013-12-16 10:04:28 -06:00 committed by Tim Graham
parent 52325b0a04
commit aef019de61
4 changed files with 50 additions and 3 deletions

View File

@ -1,3 +1,4 @@
from importlib import import_module
import os import os
from optparse import make_option from optparse import make_option
import unittest import unittest
@ -89,11 +90,11 @@ class DiscoverRunner(object):
break break
kwargs['top_level_dir'] = top_level kwargs['top_level_dir'] = top_level
if not (tests and tests.countTestCases()): if not (tests and tests.countTestCases()) and is_discoverable(label):
# if no tests found, it's probably a package; try discovery # Try discovery if path is a package or directory
tests = self.test_loader.discover(start_dir=label, **kwargs) tests = self.test_loader.discover(start_dir=label, **kwargs)
# make unittest forget the top-level dir it calculated from this # Make unittest forget the top-level dir it calculated from this
# run, to support running tests from two different top-levels. # run, to support running tests from two different top-levels.
self.test_loader._top_level_dir = None self.test_loader._top_level_dir = None
@ -150,6 +151,20 @@ class DiscoverRunner(object):
return self.suite_result(suite, result) return self.suite_result(suite, result)
def is_discoverable(label):
"""
Check if a test label points to a python package or file directory.
"""
try:
mod = import_module(label)
except ImportError:
pass
else:
return hasattr(mod, '__path__')
return os.path.isdir(os.path.abspath(label))
def dependency_ordered(test_databases, dependencies): def dependency_ordered(test_databases, dependencies):
""" """
Reorder test_databases into an order that honors the dependencies Reorder test_databases into an order that honors the dependencies

View File

View File

@ -13,3 +13,7 @@ class TestDjangoTestCase(DjangoTestCase):
def test_sample(self): def test_sample(self):
self.assertEqual(1, 1) self.assertEqual(1, 1)
class EmptyTestCase(TestCase):
pass

View File

@ -68,6 +68,34 @@ class DiscoverRunnerTest(TestCase):
self.assertEqual(count, 3) self.assertEqual(count, 3)
def test_empty_test_case(self):
count = DiscoverRunner().build_suite(
["test_discovery_sample.tests_sample.EmptyTestCase"],
).countTestCases()
self.assertEqual(count, 0)
def test_discovery_on_package(self):
count = DiscoverRunner().build_suite(
["test_discovery_sample.tests"],
).countTestCases()
self.assertEqual(count, 1)
def test_ignore_adjacent(self):
"""
When given a dotted path to a module, unittest discovery searches
not just the module, but also the directory containing the module.
This results in tests from adjacent modules being run when they
should not. The discover runner avoids this behavior.
"""
count = DiscoverRunner().build_suite(
["test_discovery_sample.empty"],
).countTestCases()
self.assertEqual(count, 0)
def test_overrideable_test_suite(self): def test_overrideable_test_suite(self):
self.assertEqual(DiscoverRunner().test_suite, TestSuite) self.assertEqual(DiscoverRunner().test_suite, TestSuite)