17db96d56Sopenharmony_ciimport os.path 27db96d56Sopenharmony_cifrom os.path import abspath 37db96d56Sopenharmony_ciimport re 47db96d56Sopenharmony_ciimport sys 57db96d56Sopenharmony_ciimport types 67db96d56Sopenharmony_ciimport pickle 77db96d56Sopenharmony_cifrom test import support 87db96d56Sopenharmony_cifrom test.support import import_helper 97db96d56Sopenharmony_ciimport test.test_importlib.util 107db96d56Sopenharmony_ci 117db96d56Sopenharmony_ciimport unittest 127db96d56Sopenharmony_ciimport unittest.mock 137db96d56Sopenharmony_ciimport unittest.test 147db96d56Sopenharmony_ci 157db96d56Sopenharmony_ci 167db96d56Sopenharmony_ciclass TestableTestProgram(unittest.TestProgram): 177db96d56Sopenharmony_ci module = None 187db96d56Sopenharmony_ci exit = True 197db96d56Sopenharmony_ci defaultTest = failfast = catchbreak = buffer = None 207db96d56Sopenharmony_ci verbosity = 1 217db96d56Sopenharmony_ci progName = '' 227db96d56Sopenharmony_ci testRunner = testLoader = None 237db96d56Sopenharmony_ci 247db96d56Sopenharmony_ci def __init__(self): 257db96d56Sopenharmony_ci pass 267db96d56Sopenharmony_ci 277db96d56Sopenharmony_ci 287db96d56Sopenharmony_ciclass TestDiscovery(unittest.TestCase): 297db96d56Sopenharmony_ci 307db96d56Sopenharmony_ci # Heavily mocked tests so I can avoid hitting the filesystem 317db96d56Sopenharmony_ci def test_get_name_from_path(self): 327db96d56Sopenharmony_ci loader = unittest.TestLoader() 337db96d56Sopenharmony_ci loader._top_level_dir = '/foo' 347db96d56Sopenharmony_ci name = loader._get_name_from_path('/foo/bar/baz.py') 357db96d56Sopenharmony_ci self.assertEqual(name, 'bar.baz') 367db96d56Sopenharmony_ci 377db96d56Sopenharmony_ci if not __debug__: 387db96d56Sopenharmony_ci # asserts are off 397db96d56Sopenharmony_ci return 407db96d56Sopenharmony_ci 417db96d56Sopenharmony_ci with self.assertRaises(AssertionError): 427db96d56Sopenharmony_ci loader._get_name_from_path('/bar/baz.py') 437db96d56Sopenharmony_ci 447db96d56Sopenharmony_ci def test_find_tests(self): 457db96d56Sopenharmony_ci loader = unittest.TestLoader() 467db96d56Sopenharmony_ci 477db96d56Sopenharmony_ci original_listdir = os.listdir 487db96d56Sopenharmony_ci def restore_listdir(): 497db96d56Sopenharmony_ci os.listdir = original_listdir 507db96d56Sopenharmony_ci original_isfile = os.path.isfile 517db96d56Sopenharmony_ci def restore_isfile(): 527db96d56Sopenharmony_ci os.path.isfile = original_isfile 537db96d56Sopenharmony_ci original_isdir = os.path.isdir 547db96d56Sopenharmony_ci def restore_isdir(): 557db96d56Sopenharmony_ci os.path.isdir = original_isdir 567db96d56Sopenharmony_ci 577db96d56Sopenharmony_ci path_lists = [['test2.py', 'test1.py', 'not_a_test.py', 'test_dir', 587db96d56Sopenharmony_ci 'test.foo', 'test-not-a-module.py', 'another_dir'], 597db96d56Sopenharmony_ci ['test4.py', 'test3.py', ]] 607db96d56Sopenharmony_ci os.listdir = lambda path: path_lists.pop(0) 617db96d56Sopenharmony_ci self.addCleanup(restore_listdir) 627db96d56Sopenharmony_ci 637db96d56Sopenharmony_ci def isdir(path): 647db96d56Sopenharmony_ci return path.endswith('dir') 657db96d56Sopenharmony_ci os.path.isdir = isdir 667db96d56Sopenharmony_ci self.addCleanup(restore_isdir) 677db96d56Sopenharmony_ci 687db96d56Sopenharmony_ci def isfile(path): 697db96d56Sopenharmony_ci # another_dir is not a package and so shouldn't be recursed into 707db96d56Sopenharmony_ci return not path.endswith('dir') and not 'another_dir' in path 717db96d56Sopenharmony_ci os.path.isfile = isfile 727db96d56Sopenharmony_ci self.addCleanup(restore_isfile) 737db96d56Sopenharmony_ci 747db96d56Sopenharmony_ci loader._get_module_from_name = lambda path: path + ' module' 757db96d56Sopenharmony_ci orig_load_tests = loader.loadTestsFromModule 767db96d56Sopenharmony_ci def loadTestsFromModule(module, pattern=None): 777db96d56Sopenharmony_ci # This is where load_tests is called. 787db96d56Sopenharmony_ci base = orig_load_tests(module, pattern=pattern) 797db96d56Sopenharmony_ci return base + [module + ' tests'] 807db96d56Sopenharmony_ci loader.loadTestsFromModule = loadTestsFromModule 817db96d56Sopenharmony_ci loader.suiteClass = lambda thing: thing 827db96d56Sopenharmony_ci 837db96d56Sopenharmony_ci top_level = os.path.abspath('/foo') 847db96d56Sopenharmony_ci loader._top_level_dir = top_level 857db96d56Sopenharmony_ci suite = list(loader._find_tests(top_level, 'test*.py')) 867db96d56Sopenharmony_ci 877db96d56Sopenharmony_ci # The test suites found should be sorted alphabetically for reliable 887db96d56Sopenharmony_ci # execution order. 897db96d56Sopenharmony_ci expected = [[name + ' module tests'] for name in 907db96d56Sopenharmony_ci ('test1', 'test2', 'test_dir')] 917db96d56Sopenharmony_ci expected.extend([[('test_dir.%s' % name) + ' module tests'] for name in 927db96d56Sopenharmony_ci ('test3', 'test4')]) 937db96d56Sopenharmony_ci self.assertEqual(suite, expected) 947db96d56Sopenharmony_ci 957db96d56Sopenharmony_ci def test_find_tests_socket(self): 967db96d56Sopenharmony_ci # A socket is neither a directory nor a regular file. 977db96d56Sopenharmony_ci # https://bugs.python.org/issue25320 987db96d56Sopenharmony_ci loader = unittest.TestLoader() 997db96d56Sopenharmony_ci 1007db96d56Sopenharmony_ci original_listdir = os.listdir 1017db96d56Sopenharmony_ci def restore_listdir(): 1027db96d56Sopenharmony_ci os.listdir = original_listdir 1037db96d56Sopenharmony_ci original_isfile = os.path.isfile 1047db96d56Sopenharmony_ci def restore_isfile(): 1057db96d56Sopenharmony_ci os.path.isfile = original_isfile 1067db96d56Sopenharmony_ci original_isdir = os.path.isdir 1077db96d56Sopenharmony_ci def restore_isdir(): 1087db96d56Sopenharmony_ci os.path.isdir = original_isdir 1097db96d56Sopenharmony_ci 1107db96d56Sopenharmony_ci path_lists = [['socket']] 1117db96d56Sopenharmony_ci os.listdir = lambda path: path_lists.pop(0) 1127db96d56Sopenharmony_ci self.addCleanup(restore_listdir) 1137db96d56Sopenharmony_ci 1147db96d56Sopenharmony_ci os.path.isdir = lambda path: False 1157db96d56Sopenharmony_ci self.addCleanup(restore_isdir) 1167db96d56Sopenharmony_ci 1177db96d56Sopenharmony_ci os.path.isfile = lambda path: False 1187db96d56Sopenharmony_ci self.addCleanup(restore_isfile) 1197db96d56Sopenharmony_ci 1207db96d56Sopenharmony_ci loader._get_module_from_name = lambda path: path + ' module' 1217db96d56Sopenharmony_ci orig_load_tests = loader.loadTestsFromModule 1227db96d56Sopenharmony_ci def loadTestsFromModule(module, pattern=None): 1237db96d56Sopenharmony_ci # This is where load_tests is called. 1247db96d56Sopenharmony_ci base = orig_load_tests(module, pattern=pattern) 1257db96d56Sopenharmony_ci return base + [module + ' tests'] 1267db96d56Sopenharmony_ci loader.loadTestsFromModule = loadTestsFromModule 1277db96d56Sopenharmony_ci loader.suiteClass = lambda thing: thing 1287db96d56Sopenharmony_ci 1297db96d56Sopenharmony_ci top_level = os.path.abspath('/foo') 1307db96d56Sopenharmony_ci loader._top_level_dir = top_level 1317db96d56Sopenharmony_ci suite = list(loader._find_tests(top_level, 'test*.py')) 1327db96d56Sopenharmony_ci 1337db96d56Sopenharmony_ci self.assertEqual(suite, []) 1347db96d56Sopenharmony_ci 1357db96d56Sopenharmony_ci def test_find_tests_with_package(self): 1367db96d56Sopenharmony_ci loader = unittest.TestLoader() 1377db96d56Sopenharmony_ci 1387db96d56Sopenharmony_ci original_listdir = os.listdir 1397db96d56Sopenharmony_ci def restore_listdir(): 1407db96d56Sopenharmony_ci os.listdir = original_listdir 1417db96d56Sopenharmony_ci original_isfile = os.path.isfile 1427db96d56Sopenharmony_ci def restore_isfile(): 1437db96d56Sopenharmony_ci os.path.isfile = original_isfile 1447db96d56Sopenharmony_ci original_isdir = os.path.isdir 1457db96d56Sopenharmony_ci def restore_isdir(): 1467db96d56Sopenharmony_ci os.path.isdir = original_isdir 1477db96d56Sopenharmony_ci 1487db96d56Sopenharmony_ci directories = ['a_directory', 'test_directory', 'test_directory2'] 1497db96d56Sopenharmony_ci path_lists = [directories, [], [], []] 1507db96d56Sopenharmony_ci os.listdir = lambda path: path_lists.pop(0) 1517db96d56Sopenharmony_ci self.addCleanup(restore_listdir) 1527db96d56Sopenharmony_ci 1537db96d56Sopenharmony_ci os.path.isdir = lambda path: True 1547db96d56Sopenharmony_ci self.addCleanup(restore_isdir) 1557db96d56Sopenharmony_ci 1567db96d56Sopenharmony_ci os.path.isfile = lambda path: os.path.basename(path) not in directories 1577db96d56Sopenharmony_ci self.addCleanup(restore_isfile) 1587db96d56Sopenharmony_ci 1597db96d56Sopenharmony_ci class Module(object): 1607db96d56Sopenharmony_ci paths = [] 1617db96d56Sopenharmony_ci load_tests_args = [] 1627db96d56Sopenharmony_ci 1637db96d56Sopenharmony_ci def __init__(self, path): 1647db96d56Sopenharmony_ci self.path = path 1657db96d56Sopenharmony_ci self.paths.append(path) 1667db96d56Sopenharmony_ci if os.path.basename(path) == 'test_directory': 1677db96d56Sopenharmony_ci def load_tests(loader, tests, pattern): 1687db96d56Sopenharmony_ci self.load_tests_args.append((loader, tests, pattern)) 1697db96d56Sopenharmony_ci return [self.path + ' load_tests'] 1707db96d56Sopenharmony_ci self.load_tests = load_tests 1717db96d56Sopenharmony_ci 1727db96d56Sopenharmony_ci def __eq__(self, other): 1737db96d56Sopenharmony_ci return self.path == other.path 1747db96d56Sopenharmony_ci 1757db96d56Sopenharmony_ci loader._get_module_from_name = lambda name: Module(name) 1767db96d56Sopenharmony_ci orig_load_tests = loader.loadTestsFromModule 1777db96d56Sopenharmony_ci def loadTestsFromModule(module, pattern=None): 1787db96d56Sopenharmony_ci # This is where load_tests is called. 1797db96d56Sopenharmony_ci base = orig_load_tests(module, pattern=pattern) 1807db96d56Sopenharmony_ci return base + [module.path + ' module tests'] 1817db96d56Sopenharmony_ci loader.loadTestsFromModule = loadTestsFromModule 1827db96d56Sopenharmony_ci loader.suiteClass = lambda thing: thing 1837db96d56Sopenharmony_ci 1847db96d56Sopenharmony_ci loader._top_level_dir = '/foo' 1857db96d56Sopenharmony_ci # this time no '.py' on the pattern so that it can match 1867db96d56Sopenharmony_ci # a test package 1877db96d56Sopenharmony_ci suite = list(loader._find_tests('/foo', 'test*')) 1887db96d56Sopenharmony_ci 1897db96d56Sopenharmony_ci # We should have loaded tests from the a_directory and test_directory2 1907db96d56Sopenharmony_ci # directly and via load_tests for the test_directory package, which 1917db96d56Sopenharmony_ci # still calls the baseline module loader. 1927db96d56Sopenharmony_ci self.assertEqual(suite, 1937db96d56Sopenharmony_ci [['a_directory module tests'], 1947db96d56Sopenharmony_ci ['test_directory load_tests', 1957db96d56Sopenharmony_ci 'test_directory module tests'], 1967db96d56Sopenharmony_ci ['test_directory2 module tests']]) 1977db96d56Sopenharmony_ci 1987db96d56Sopenharmony_ci 1997db96d56Sopenharmony_ci # The test module paths should be sorted for reliable execution order 2007db96d56Sopenharmony_ci self.assertEqual(Module.paths, 2017db96d56Sopenharmony_ci ['a_directory', 'test_directory', 'test_directory2']) 2027db96d56Sopenharmony_ci 2037db96d56Sopenharmony_ci # load_tests should have been called once with loader, tests and pattern 2047db96d56Sopenharmony_ci # (but there are no tests in our stub module itself, so that is [] at 2057db96d56Sopenharmony_ci # the time of call). 2067db96d56Sopenharmony_ci self.assertEqual(Module.load_tests_args, 2077db96d56Sopenharmony_ci [(loader, [], 'test*')]) 2087db96d56Sopenharmony_ci 2097db96d56Sopenharmony_ci def test_find_tests_default_calls_package_load_tests(self): 2107db96d56Sopenharmony_ci loader = unittest.TestLoader() 2117db96d56Sopenharmony_ci 2127db96d56Sopenharmony_ci original_listdir = os.listdir 2137db96d56Sopenharmony_ci def restore_listdir(): 2147db96d56Sopenharmony_ci os.listdir = original_listdir 2157db96d56Sopenharmony_ci original_isfile = os.path.isfile 2167db96d56Sopenharmony_ci def restore_isfile(): 2177db96d56Sopenharmony_ci os.path.isfile = original_isfile 2187db96d56Sopenharmony_ci original_isdir = os.path.isdir 2197db96d56Sopenharmony_ci def restore_isdir(): 2207db96d56Sopenharmony_ci os.path.isdir = original_isdir 2217db96d56Sopenharmony_ci 2227db96d56Sopenharmony_ci directories = ['a_directory', 'test_directory', 'test_directory2'] 2237db96d56Sopenharmony_ci path_lists = [directories, [], [], []] 2247db96d56Sopenharmony_ci os.listdir = lambda path: path_lists.pop(0) 2257db96d56Sopenharmony_ci self.addCleanup(restore_listdir) 2267db96d56Sopenharmony_ci 2277db96d56Sopenharmony_ci os.path.isdir = lambda path: True 2287db96d56Sopenharmony_ci self.addCleanup(restore_isdir) 2297db96d56Sopenharmony_ci 2307db96d56Sopenharmony_ci os.path.isfile = lambda path: os.path.basename(path) not in directories 2317db96d56Sopenharmony_ci self.addCleanup(restore_isfile) 2327db96d56Sopenharmony_ci 2337db96d56Sopenharmony_ci class Module(object): 2347db96d56Sopenharmony_ci paths = [] 2357db96d56Sopenharmony_ci load_tests_args = [] 2367db96d56Sopenharmony_ci 2377db96d56Sopenharmony_ci def __init__(self, path): 2387db96d56Sopenharmony_ci self.path = path 2397db96d56Sopenharmony_ci self.paths.append(path) 2407db96d56Sopenharmony_ci if os.path.basename(path) == 'test_directory': 2417db96d56Sopenharmony_ci def load_tests(loader, tests, pattern): 2427db96d56Sopenharmony_ci self.load_tests_args.append((loader, tests, pattern)) 2437db96d56Sopenharmony_ci return [self.path + ' load_tests'] 2447db96d56Sopenharmony_ci self.load_tests = load_tests 2457db96d56Sopenharmony_ci 2467db96d56Sopenharmony_ci def __eq__(self, other): 2477db96d56Sopenharmony_ci return self.path == other.path 2487db96d56Sopenharmony_ci 2497db96d56Sopenharmony_ci loader._get_module_from_name = lambda name: Module(name) 2507db96d56Sopenharmony_ci orig_load_tests = loader.loadTestsFromModule 2517db96d56Sopenharmony_ci def loadTestsFromModule(module, pattern=None): 2527db96d56Sopenharmony_ci # This is where load_tests is called. 2537db96d56Sopenharmony_ci base = orig_load_tests(module, pattern=pattern) 2547db96d56Sopenharmony_ci return base + [module.path + ' module tests'] 2557db96d56Sopenharmony_ci loader.loadTestsFromModule = loadTestsFromModule 2567db96d56Sopenharmony_ci loader.suiteClass = lambda thing: thing 2577db96d56Sopenharmony_ci 2587db96d56Sopenharmony_ci loader._top_level_dir = '/foo' 2597db96d56Sopenharmony_ci # this time no '.py' on the pattern so that it can match 2607db96d56Sopenharmony_ci # a test package 2617db96d56Sopenharmony_ci suite = list(loader._find_tests('/foo', 'test*.py')) 2627db96d56Sopenharmony_ci 2637db96d56Sopenharmony_ci # We should have loaded tests from the a_directory and test_directory2 2647db96d56Sopenharmony_ci # directly and via load_tests for the test_directory package, which 2657db96d56Sopenharmony_ci # still calls the baseline module loader. 2667db96d56Sopenharmony_ci self.assertEqual(suite, 2677db96d56Sopenharmony_ci [['a_directory module tests'], 2687db96d56Sopenharmony_ci ['test_directory load_tests', 2697db96d56Sopenharmony_ci 'test_directory module tests'], 2707db96d56Sopenharmony_ci ['test_directory2 module tests']]) 2717db96d56Sopenharmony_ci # The test module paths should be sorted for reliable execution order 2727db96d56Sopenharmony_ci self.assertEqual(Module.paths, 2737db96d56Sopenharmony_ci ['a_directory', 'test_directory', 'test_directory2']) 2747db96d56Sopenharmony_ci 2757db96d56Sopenharmony_ci 2767db96d56Sopenharmony_ci # load_tests should have been called once with loader, tests and pattern 2777db96d56Sopenharmony_ci self.assertEqual(Module.load_tests_args, 2787db96d56Sopenharmony_ci [(loader, [], 'test*.py')]) 2797db96d56Sopenharmony_ci 2807db96d56Sopenharmony_ci def test_find_tests_customize_via_package_pattern(self): 2817db96d56Sopenharmony_ci # This test uses the example 'do-nothing' load_tests from 2827db96d56Sopenharmony_ci # https://docs.python.org/3/library/unittest.html#load-tests-protocol 2837db96d56Sopenharmony_ci # to make sure that that actually works. 2847db96d56Sopenharmony_ci # Housekeeping 2857db96d56Sopenharmony_ci original_listdir = os.listdir 2867db96d56Sopenharmony_ci def restore_listdir(): 2877db96d56Sopenharmony_ci os.listdir = original_listdir 2887db96d56Sopenharmony_ci self.addCleanup(restore_listdir) 2897db96d56Sopenharmony_ci original_isfile = os.path.isfile 2907db96d56Sopenharmony_ci def restore_isfile(): 2917db96d56Sopenharmony_ci os.path.isfile = original_isfile 2927db96d56Sopenharmony_ci self.addCleanup(restore_isfile) 2937db96d56Sopenharmony_ci original_isdir = os.path.isdir 2947db96d56Sopenharmony_ci def restore_isdir(): 2957db96d56Sopenharmony_ci os.path.isdir = original_isdir 2967db96d56Sopenharmony_ci self.addCleanup(restore_isdir) 2977db96d56Sopenharmony_ci self.addCleanup(sys.path.remove, abspath('/foo')) 2987db96d56Sopenharmony_ci 2997db96d56Sopenharmony_ci # Test data: we expect the following: 3007db96d56Sopenharmony_ci # a listdir to find our package, and isfile and isdir checks on it. 3017db96d56Sopenharmony_ci # a module-from-name call to turn that into a module 3027db96d56Sopenharmony_ci # followed by load_tests. 3037db96d56Sopenharmony_ci # then our load_tests will call discover() which is messy 3047db96d56Sopenharmony_ci # but that finally chains into find_tests again for the child dir - 3057db96d56Sopenharmony_ci # which is why we don't have an infinite loop. 3067db96d56Sopenharmony_ci # We expect to see: 3077db96d56Sopenharmony_ci # the module load tests for both package and plain module called, 3087db96d56Sopenharmony_ci # and the plain module result nested by the package module load_tests 3097db96d56Sopenharmony_ci # indicating that it was processed and could have been mutated. 3107db96d56Sopenharmony_ci vfs = {abspath('/foo'): ['my_package'], 3117db96d56Sopenharmony_ci abspath('/foo/my_package'): ['__init__.py', 'test_module.py']} 3127db96d56Sopenharmony_ci def list_dir(path): 3137db96d56Sopenharmony_ci return list(vfs[path]) 3147db96d56Sopenharmony_ci os.listdir = list_dir 3157db96d56Sopenharmony_ci os.path.isdir = lambda path: not path.endswith('.py') 3167db96d56Sopenharmony_ci os.path.isfile = lambda path: path.endswith('.py') 3177db96d56Sopenharmony_ci 3187db96d56Sopenharmony_ci class Module(object): 3197db96d56Sopenharmony_ci paths = [] 3207db96d56Sopenharmony_ci load_tests_args = [] 3217db96d56Sopenharmony_ci 3227db96d56Sopenharmony_ci def __init__(self, path): 3237db96d56Sopenharmony_ci self.path = path 3247db96d56Sopenharmony_ci self.paths.append(path) 3257db96d56Sopenharmony_ci if path.endswith('test_module'): 3267db96d56Sopenharmony_ci def load_tests(loader, tests, pattern): 3277db96d56Sopenharmony_ci self.load_tests_args.append((loader, tests, pattern)) 3287db96d56Sopenharmony_ci return [self.path + ' load_tests'] 3297db96d56Sopenharmony_ci else: 3307db96d56Sopenharmony_ci def load_tests(loader, tests, pattern): 3317db96d56Sopenharmony_ci self.load_tests_args.append((loader, tests, pattern)) 3327db96d56Sopenharmony_ci # top level directory cached on loader instance 3337db96d56Sopenharmony_ci __file__ = '/foo/my_package/__init__.py' 3347db96d56Sopenharmony_ci this_dir = os.path.dirname(__file__) 3357db96d56Sopenharmony_ci pkg_tests = loader.discover( 3367db96d56Sopenharmony_ci start_dir=this_dir, pattern=pattern) 3377db96d56Sopenharmony_ci return [self.path + ' load_tests', tests 3387db96d56Sopenharmony_ci ] + pkg_tests 3397db96d56Sopenharmony_ci self.load_tests = load_tests 3407db96d56Sopenharmony_ci 3417db96d56Sopenharmony_ci def __eq__(self, other): 3427db96d56Sopenharmony_ci return self.path == other.path 3437db96d56Sopenharmony_ci 3447db96d56Sopenharmony_ci loader = unittest.TestLoader() 3457db96d56Sopenharmony_ci loader._get_module_from_name = lambda name: Module(name) 3467db96d56Sopenharmony_ci loader.suiteClass = lambda thing: thing 3477db96d56Sopenharmony_ci 3487db96d56Sopenharmony_ci loader._top_level_dir = abspath('/foo') 3497db96d56Sopenharmony_ci # this time no '.py' on the pattern so that it can match 3507db96d56Sopenharmony_ci # a test package 3517db96d56Sopenharmony_ci suite = list(loader._find_tests(abspath('/foo'), 'test*.py')) 3527db96d56Sopenharmony_ci 3537db96d56Sopenharmony_ci # We should have loaded tests from both my_package and 3547db96d56Sopenharmony_ci # my_package.test_module, and also run the load_tests hook in both. 3557db96d56Sopenharmony_ci # (normally this would be nested TestSuites.) 3567db96d56Sopenharmony_ci self.assertEqual(suite, 3577db96d56Sopenharmony_ci [['my_package load_tests', [], 3587db96d56Sopenharmony_ci ['my_package.test_module load_tests']]]) 3597db96d56Sopenharmony_ci # Parents before children. 3607db96d56Sopenharmony_ci self.assertEqual(Module.paths, 3617db96d56Sopenharmony_ci ['my_package', 'my_package.test_module']) 3627db96d56Sopenharmony_ci 3637db96d56Sopenharmony_ci # load_tests should have been called twice with loader, tests and pattern 3647db96d56Sopenharmony_ci self.assertEqual(Module.load_tests_args, 3657db96d56Sopenharmony_ci [(loader, [], 'test*.py'), 3667db96d56Sopenharmony_ci (loader, [], 'test*.py')]) 3677db96d56Sopenharmony_ci 3687db96d56Sopenharmony_ci def test_discover(self): 3697db96d56Sopenharmony_ci loader = unittest.TestLoader() 3707db96d56Sopenharmony_ci 3717db96d56Sopenharmony_ci original_isfile = os.path.isfile 3727db96d56Sopenharmony_ci original_isdir = os.path.isdir 3737db96d56Sopenharmony_ci def restore_isfile(): 3747db96d56Sopenharmony_ci os.path.isfile = original_isfile 3757db96d56Sopenharmony_ci 3767db96d56Sopenharmony_ci os.path.isfile = lambda path: False 3777db96d56Sopenharmony_ci self.addCleanup(restore_isfile) 3787db96d56Sopenharmony_ci 3797db96d56Sopenharmony_ci orig_sys_path = sys.path[:] 3807db96d56Sopenharmony_ci def restore_path(): 3817db96d56Sopenharmony_ci sys.path[:] = orig_sys_path 3827db96d56Sopenharmony_ci self.addCleanup(restore_path) 3837db96d56Sopenharmony_ci 3847db96d56Sopenharmony_ci full_path = os.path.abspath(os.path.normpath('/foo')) 3857db96d56Sopenharmony_ci with self.assertRaises(ImportError): 3867db96d56Sopenharmony_ci loader.discover('/foo/bar', top_level_dir='/foo') 3877db96d56Sopenharmony_ci 3887db96d56Sopenharmony_ci self.assertEqual(loader._top_level_dir, full_path) 3897db96d56Sopenharmony_ci self.assertIn(full_path, sys.path) 3907db96d56Sopenharmony_ci 3917db96d56Sopenharmony_ci os.path.isfile = lambda path: True 3927db96d56Sopenharmony_ci os.path.isdir = lambda path: True 3937db96d56Sopenharmony_ci 3947db96d56Sopenharmony_ci def restore_isdir(): 3957db96d56Sopenharmony_ci os.path.isdir = original_isdir 3967db96d56Sopenharmony_ci self.addCleanup(restore_isdir) 3977db96d56Sopenharmony_ci 3987db96d56Sopenharmony_ci _find_tests_args = [] 3997db96d56Sopenharmony_ci def _find_tests(start_dir, pattern): 4007db96d56Sopenharmony_ci _find_tests_args.append((start_dir, pattern)) 4017db96d56Sopenharmony_ci return ['tests'] 4027db96d56Sopenharmony_ci loader._find_tests = _find_tests 4037db96d56Sopenharmony_ci loader.suiteClass = str 4047db96d56Sopenharmony_ci 4057db96d56Sopenharmony_ci suite = loader.discover('/foo/bar/baz', 'pattern', '/foo/bar') 4067db96d56Sopenharmony_ci 4077db96d56Sopenharmony_ci top_level_dir = os.path.abspath('/foo/bar') 4087db96d56Sopenharmony_ci start_dir = os.path.abspath('/foo/bar/baz') 4097db96d56Sopenharmony_ci self.assertEqual(suite, "['tests']") 4107db96d56Sopenharmony_ci self.assertEqual(loader._top_level_dir, top_level_dir) 4117db96d56Sopenharmony_ci self.assertEqual(_find_tests_args, [(start_dir, 'pattern')]) 4127db96d56Sopenharmony_ci self.assertIn(top_level_dir, sys.path) 4137db96d56Sopenharmony_ci 4147db96d56Sopenharmony_ci def test_discover_start_dir_is_package_calls_package_load_tests(self): 4157db96d56Sopenharmony_ci # This test verifies that the package load_tests in a package is indeed 4167db96d56Sopenharmony_ci # invoked when the start_dir is a package (and not the top level). 4177db96d56Sopenharmony_ci # http://bugs.python.org/issue22457 4187db96d56Sopenharmony_ci 4197db96d56Sopenharmony_ci # Test data: we expect the following: 4207db96d56Sopenharmony_ci # an isfile to verify the package, then importing and scanning 4217db96d56Sopenharmony_ci # as per _find_tests' normal behaviour. 4227db96d56Sopenharmony_ci # We expect to see our load_tests hook called once. 4237db96d56Sopenharmony_ci vfs = {abspath('/toplevel'): ['startdir'], 4247db96d56Sopenharmony_ci abspath('/toplevel/startdir'): ['__init__.py']} 4257db96d56Sopenharmony_ci def list_dir(path): 4267db96d56Sopenharmony_ci return list(vfs[path]) 4277db96d56Sopenharmony_ci self.addCleanup(setattr, os, 'listdir', os.listdir) 4287db96d56Sopenharmony_ci os.listdir = list_dir 4297db96d56Sopenharmony_ci self.addCleanup(setattr, os.path, 'isfile', os.path.isfile) 4307db96d56Sopenharmony_ci os.path.isfile = lambda path: path.endswith('.py') 4317db96d56Sopenharmony_ci self.addCleanup(setattr, os.path, 'isdir', os.path.isdir) 4327db96d56Sopenharmony_ci os.path.isdir = lambda path: not path.endswith('.py') 4337db96d56Sopenharmony_ci self.addCleanup(sys.path.remove, abspath('/toplevel')) 4347db96d56Sopenharmony_ci 4357db96d56Sopenharmony_ci class Module(object): 4367db96d56Sopenharmony_ci paths = [] 4377db96d56Sopenharmony_ci load_tests_args = [] 4387db96d56Sopenharmony_ci 4397db96d56Sopenharmony_ci def __init__(self, path): 4407db96d56Sopenharmony_ci self.path = path 4417db96d56Sopenharmony_ci 4427db96d56Sopenharmony_ci def load_tests(self, loader, tests, pattern): 4437db96d56Sopenharmony_ci return ['load_tests called ' + self.path] 4447db96d56Sopenharmony_ci 4457db96d56Sopenharmony_ci def __eq__(self, other): 4467db96d56Sopenharmony_ci return self.path == other.path 4477db96d56Sopenharmony_ci 4487db96d56Sopenharmony_ci loader = unittest.TestLoader() 4497db96d56Sopenharmony_ci loader._get_module_from_name = lambda name: Module(name) 4507db96d56Sopenharmony_ci loader.suiteClass = lambda thing: thing 4517db96d56Sopenharmony_ci 4527db96d56Sopenharmony_ci suite = loader.discover('/toplevel/startdir', top_level_dir='/toplevel') 4537db96d56Sopenharmony_ci 4547db96d56Sopenharmony_ci # We should have loaded tests from the package __init__. 4557db96d56Sopenharmony_ci # (normally this would be nested TestSuites.) 4567db96d56Sopenharmony_ci self.assertEqual(suite, 4577db96d56Sopenharmony_ci [['load_tests called startdir']]) 4587db96d56Sopenharmony_ci 4597db96d56Sopenharmony_ci def setup_import_issue_tests(self, fakefile): 4607db96d56Sopenharmony_ci listdir = os.listdir 4617db96d56Sopenharmony_ci os.listdir = lambda _: [fakefile] 4627db96d56Sopenharmony_ci isfile = os.path.isfile 4637db96d56Sopenharmony_ci os.path.isfile = lambda _: True 4647db96d56Sopenharmony_ci orig_sys_path = sys.path[:] 4657db96d56Sopenharmony_ci def restore(): 4667db96d56Sopenharmony_ci os.path.isfile = isfile 4677db96d56Sopenharmony_ci os.listdir = listdir 4687db96d56Sopenharmony_ci sys.path[:] = orig_sys_path 4697db96d56Sopenharmony_ci self.addCleanup(restore) 4707db96d56Sopenharmony_ci 4717db96d56Sopenharmony_ci def setup_import_issue_package_tests(self, vfs): 4727db96d56Sopenharmony_ci self.addCleanup(setattr, os, 'listdir', os.listdir) 4737db96d56Sopenharmony_ci self.addCleanup(setattr, os.path, 'isfile', os.path.isfile) 4747db96d56Sopenharmony_ci self.addCleanup(setattr, os.path, 'isdir', os.path.isdir) 4757db96d56Sopenharmony_ci self.addCleanup(sys.path.__setitem__, slice(None), list(sys.path)) 4767db96d56Sopenharmony_ci def list_dir(path): 4777db96d56Sopenharmony_ci return list(vfs[path]) 4787db96d56Sopenharmony_ci os.listdir = list_dir 4797db96d56Sopenharmony_ci os.path.isdir = lambda path: not path.endswith('.py') 4807db96d56Sopenharmony_ci os.path.isfile = lambda path: path.endswith('.py') 4817db96d56Sopenharmony_ci 4827db96d56Sopenharmony_ci def test_discover_with_modules_that_fail_to_import(self): 4837db96d56Sopenharmony_ci loader = unittest.TestLoader() 4847db96d56Sopenharmony_ci 4857db96d56Sopenharmony_ci self.setup_import_issue_tests('test_this_does_not_exist.py') 4867db96d56Sopenharmony_ci 4877db96d56Sopenharmony_ci suite = loader.discover('.') 4887db96d56Sopenharmony_ci self.assertIn(os.getcwd(), sys.path) 4897db96d56Sopenharmony_ci self.assertEqual(suite.countTestCases(), 1) 4907db96d56Sopenharmony_ci # Errors loading the suite are also captured for introspection. 4917db96d56Sopenharmony_ci self.assertNotEqual([], loader.errors) 4927db96d56Sopenharmony_ci self.assertEqual(1, len(loader.errors)) 4937db96d56Sopenharmony_ci error = loader.errors[0] 4947db96d56Sopenharmony_ci self.assertTrue( 4957db96d56Sopenharmony_ci 'Failed to import test module: test_this_does_not_exist' in error, 4967db96d56Sopenharmony_ci 'missing error string in %r' % error) 4977db96d56Sopenharmony_ci test = list(list(suite)[0])[0] # extract test from suite 4987db96d56Sopenharmony_ci 4997db96d56Sopenharmony_ci with self.assertRaises(ImportError): 5007db96d56Sopenharmony_ci test.test_this_does_not_exist() 5017db96d56Sopenharmony_ci 5027db96d56Sopenharmony_ci def test_discover_with_init_modules_that_fail_to_import(self): 5037db96d56Sopenharmony_ci vfs = {abspath('/foo'): ['my_package'], 5047db96d56Sopenharmony_ci abspath('/foo/my_package'): ['__init__.py', 'test_module.py']} 5057db96d56Sopenharmony_ci self.setup_import_issue_package_tests(vfs) 5067db96d56Sopenharmony_ci import_calls = [] 5077db96d56Sopenharmony_ci def _get_module_from_name(name): 5087db96d56Sopenharmony_ci import_calls.append(name) 5097db96d56Sopenharmony_ci raise ImportError("Cannot import Name") 5107db96d56Sopenharmony_ci loader = unittest.TestLoader() 5117db96d56Sopenharmony_ci loader._get_module_from_name = _get_module_from_name 5127db96d56Sopenharmony_ci suite = loader.discover(abspath('/foo')) 5137db96d56Sopenharmony_ci 5147db96d56Sopenharmony_ci self.assertIn(abspath('/foo'), sys.path) 5157db96d56Sopenharmony_ci self.assertEqual(suite.countTestCases(), 1) 5167db96d56Sopenharmony_ci # Errors loading the suite are also captured for introspection. 5177db96d56Sopenharmony_ci self.assertNotEqual([], loader.errors) 5187db96d56Sopenharmony_ci self.assertEqual(1, len(loader.errors)) 5197db96d56Sopenharmony_ci error = loader.errors[0] 5207db96d56Sopenharmony_ci self.assertTrue( 5217db96d56Sopenharmony_ci 'Failed to import test module: my_package' in error, 5227db96d56Sopenharmony_ci 'missing error string in %r' % error) 5237db96d56Sopenharmony_ci test = list(list(suite)[0])[0] # extract test from suite 5247db96d56Sopenharmony_ci with self.assertRaises(ImportError): 5257db96d56Sopenharmony_ci test.my_package() 5267db96d56Sopenharmony_ci self.assertEqual(import_calls, ['my_package']) 5277db96d56Sopenharmony_ci 5287db96d56Sopenharmony_ci # Check picklability 5297db96d56Sopenharmony_ci for proto in range(pickle.HIGHEST_PROTOCOL + 1): 5307db96d56Sopenharmony_ci pickle.loads(pickle.dumps(test, proto)) 5317db96d56Sopenharmony_ci 5327db96d56Sopenharmony_ci def test_discover_with_module_that_raises_SkipTest_on_import(self): 5337db96d56Sopenharmony_ci if not unittest.BaseTestSuite._cleanup: 5347db96d56Sopenharmony_ci raise unittest.SkipTest("Suite cleanup is disabled") 5357db96d56Sopenharmony_ci 5367db96d56Sopenharmony_ci loader = unittest.TestLoader() 5377db96d56Sopenharmony_ci 5387db96d56Sopenharmony_ci def _get_module_from_name(name): 5397db96d56Sopenharmony_ci raise unittest.SkipTest('skipperoo') 5407db96d56Sopenharmony_ci loader._get_module_from_name = _get_module_from_name 5417db96d56Sopenharmony_ci 5427db96d56Sopenharmony_ci self.setup_import_issue_tests('test_skip_dummy.py') 5437db96d56Sopenharmony_ci 5447db96d56Sopenharmony_ci suite = loader.discover('.') 5457db96d56Sopenharmony_ci self.assertEqual(suite.countTestCases(), 1) 5467db96d56Sopenharmony_ci 5477db96d56Sopenharmony_ci result = unittest.TestResult() 5487db96d56Sopenharmony_ci suite.run(result) 5497db96d56Sopenharmony_ci self.assertEqual(len(result.skipped), 1) 5507db96d56Sopenharmony_ci 5517db96d56Sopenharmony_ci # Check picklability 5527db96d56Sopenharmony_ci for proto in range(pickle.HIGHEST_PROTOCOL + 1): 5537db96d56Sopenharmony_ci pickle.loads(pickle.dumps(suite, proto)) 5547db96d56Sopenharmony_ci 5557db96d56Sopenharmony_ci def test_discover_with_init_module_that_raises_SkipTest_on_import(self): 5567db96d56Sopenharmony_ci if not unittest.BaseTestSuite._cleanup: 5577db96d56Sopenharmony_ci raise unittest.SkipTest("Suite cleanup is disabled") 5587db96d56Sopenharmony_ci 5597db96d56Sopenharmony_ci vfs = {abspath('/foo'): ['my_package'], 5607db96d56Sopenharmony_ci abspath('/foo/my_package'): ['__init__.py', 'test_module.py']} 5617db96d56Sopenharmony_ci self.setup_import_issue_package_tests(vfs) 5627db96d56Sopenharmony_ci import_calls = [] 5637db96d56Sopenharmony_ci def _get_module_from_name(name): 5647db96d56Sopenharmony_ci import_calls.append(name) 5657db96d56Sopenharmony_ci raise unittest.SkipTest('skipperoo') 5667db96d56Sopenharmony_ci loader = unittest.TestLoader() 5677db96d56Sopenharmony_ci loader._get_module_from_name = _get_module_from_name 5687db96d56Sopenharmony_ci suite = loader.discover(abspath('/foo')) 5697db96d56Sopenharmony_ci 5707db96d56Sopenharmony_ci self.assertIn(abspath('/foo'), sys.path) 5717db96d56Sopenharmony_ci self.assertEqual(suite.countTestCases(), 1) 5727db96d56Sopenharmony_ci result = unittest.TestResult() 5737db96d56Sopenharmony_ci suite.run(result) 5747db96d56Sopenharmony_ci self.assertEqual(len(result.skipped), 1) 5757db96d56Sopenharmony_ci self.assertEqual(result.testsRun, 1) 5767db96d56Sopenharmony_ci self.assertEqual(import_calls, ['my_package']) 5777db96d56Sopenharmony_ci 5787db96d56Sopenharmony_ci # Check picklability 5797db96d56Sopenharmony_ci for proto in range(pickle.HIGHEST_PROTOCOL + 1): 5807db96d56Sopenharmony_ci pickle.loads(pickle.dumps(suite, proto)) 5817db96d56Sopenharmony_ci 5827db96d56Sopenharmony_ci def test_command_line_handling_parseArgs(self): 5837db96d56Sopenharmony_ci program = TestableTestProgram() 5847db96d56Sopenharmony_ci 5857db96d56Sopenharmony_ci args = [] 5867db96d56Sopenharmony_ci program._do_discovery = args.append 5877db96d56Sopenharmony_ci program.parseArgs(['something', 'discover']) 5887db96d56Sopenharmony_ci self.assertEqual(args, [[]]) 5897db96d56Sopenharmony_ci 5907db96d56Sopenharmony_ci args[:] = [] 5917db96d56Sopenharmony_ci program.parseArgs(['something', 'discover', 'foo', 'bar']) 5927db96d56Sopenharmony_ci self.assertEqual(args, [['foo', 'bar']]) 5937db96d56Sopenharmony_ci 5947db96d56Sopenharmony_ci def test_command_line_handling_discover_by_default(self): 5957db96d56Sopenharmony_ci program = TestableTestProgram() 5967db96d56Sopenharmony_ci 5977db96d56Sopenharmony_ci args = [] 5987db96d56Sopenharmony_ci program._do_discovery = args.append 5997db96d56Sopenharmony_ci program.parseArgs(['something']) 6007db96d56Sopenharmony_ci self.assertEqual(args, [[]]) 6017db96d56Sopenharmony_ci self.assertEqual(program.verbosity, 1) 6027db96d56Sopenharmony_ci self.assertIs(program.buffer, False) 6037db96d56Sopenharmony_ci self.assertIs(program.catchbreak, False) 6047db96d56Sopenharmony_ci self.assertIs(program.failfast, False) 6057db96d56Sopenharmony_ci 6067db96d56Sopenharmony_ci def test_command_line_handling_discover_by_default_with_options(self): 6077db96d56Sopenharmony_ci program = TestableTestProgram() 6087db96d56Sopenharmony_ci 6097db96d56Sopenharmony_ci args = [] 6107db96d56Sopenharmony_ci program._do_discovery = args.append 6117db96d56Sopenharmony_ci program.parseArgs(['something', '-v', '-b', '-v', '-c', '-f']) 6127db96d56Sopenharmony_ci self.assertEqual(args, [[]]) 6137db96d56Sopenharmony_ci self.assertEqual(program.verbosity, 2) 6147db96d56Sopenharmony_ci self.assertIs(program.buffer, True) 6157db96d56Sopenharmony_ci self.assertIs(program.catchbreak, True) 6167db96d56Sopenharmony_ci self.assertIs(program.failfast, True) 6177db96d56Sopenharmony_ci 6187db96d56Sopenharmony_ci 6197db96d56Sopenharmony_ci def test_command_line_handling_do_discovery_too_many_arguments(self): 6207db96d56Sopenharmony_ci program = TestableTestProgram() 6217db96d56Sopenharmony_ci program.testLoader = None 6227db96d56Sopenharmony_ci 6237db96d56Sopenharmony_ci with support.captured_stderr() as stderr, \ 6247db96d56Sopenharmony_ci self.assertRaises(SystemExit) as cm: 6257db96d56Sopenharmony_ci # too many args 6267db96d56Sopenharmony_ci program._do_discovery(['one', 'two', 'three', 'four']) 6277db96d56Sopenharmony_ci self.assertEqual(cm.exception.args, (2,)) 6287db96d56Sopenharmony_ci self.assertIn('usage:', stderr.getvalue()) 6297db96d56Sopenharmony_ci 6307db96d56Sopenharmony_ci 6317db96d56Sopenharmony_ci def test_command_line_handling_do_discovery_uses_default_loader(self): 6327db96d56Sopenharmony_ci program = object.__new__(unittest.TestProgram) 6337db96d56Sopenharmony_ci program._initArgParsers() 6347db96d56Sopenharmony_ci 6357db96d56Sopenharmony_ci class Loader(object): 6367db96d56Sopenharmony_ci args = [] 6377db96d56Sopenharmony_ci def discover(self, start_dir, pattern, top_level_dir): 6387db96d56Sopenharmony_ci self.args.append((start_dir, pattern, top_level_dir)) 6397db96d56Sopenharmony_ci return 'tests' 6407db96d56Sopenharmony_ci 6417db96d56Sopenharmony_ci program.testLoader = Loader() 6427db96d56Sopenharmony_ci program._do_discovery(['-v']) 6437db96d56Sopenharmony_ci self.assertEqual(Loader.args, [('.', 'test*.py', None)]) 6447db96d56Sopenharmony_ci 6457db96d56Sopenharmony_ci def test_command_line_handling_do_discovery_calls_loader(self): 6467db96d56Sopenharmony_ci program = TestableTestProgram() 6477db96d56Sopenharmony_ci 6487db96d56Sopenharmony_ci class Loader(object): 6497db96d56Sopenharmony_ci args = [] 6507db96d56Sopenharmony_ci def discover(self, start_dir, pattern, top_level_dir): 6517db96d56Sopenharmony_ci self.args.append((start_dir, pattern, top_level_dir)) 6527db96d56Sopenharmony_ci return 'tests' 6537db96d56Sopenharmony_ci 6547db96d56Sopenharmony_ci program._do_discovery(['-v'], Loader=Loader) 6557db96d56Sopenharmony_ci self.assertEqual(program.verbosity, 2) 6567db96d56Sopenharmony_ci self.assertEqual(program.test, 'tests') 6577db96d56Sopenharmony_ci self.assertEqual(Loader.args, [('.', 'test*.py', None)]) 6587db96d56Sopenharmony_ci 6597db96d56Sopenharmony_ci Loader.args = [] 6607db96d56Sopenharmony_ci program = TestableTestProgram() 6617db96d56Sopenharmony_ci program._do_discovery(['--verbose'], Loader=Loader) 6627db96d56Sopenharmony_ci self.assertEqual(program.test, 'tests') 6637db96d56Sopenharmony_ci self.assertEqual(Loader.args, [('.', 'test*.py', None)]) 6647db96d56Sopenharmony_ci 6657db96d56Sopenharmony_ci Loader.args = [] 6667db96d56Sopenharmony_ci program = TestableTestProgram() 6677db96d56Sopenharmony_ci program._do_discovery([], Loader=Loader) 6687db96d56Sopenharmony_ci self.assertEqual(program.test, 'tests') 6697db96d56Sopenharmony_ci self.assertEqual(Loader.args, [('.', 'test*.py', None)]) 6707db96d56Sopenharmony_ci 6717db96d56Sopenharmony_ci Loader.args = [] 6727db96d56Sopenharmony_ci program = TestableTestProgram() 6737db96d56Sopenharmony_ci program._do_discovery(['fish'], Loader=Loader) 6747db96d56Sopenharmony_ci self.assertEqual(program.test, 'tests') 6757db96d56Sopenharmony_ci self.assertEqual(Loader.args, [('fish', 'test*.py', None)]) 6767db96d56Sopenharmony_ci 6777db96d56Sopenharmony_ci Loader.args = [] 6787db96d56Sopenharmony_ci program = TestableTestProgram() 6797db96d56Sopenharmony_ci program._do_discovery(['fish', 'eggs'], Loader=Loader) 6807db96d56Sopenharmony_ci self.assertEqual(program.test, 'tests') 6817db96d56Sopenharmony_ci self.assertEqual(Loader.args, [('fish', 'eggs', None)]) 6827db96d56Sopenharmony_ci 6837db96d56Sopenharmony_ci Loader.args = [] 6847db96d56Sopenharmony_ci program = TestableTestProgram() 6857db96d56Sopenharmony_ci program._do_discovery(['fish', 'eggs', 'ham'], Loader=Loader) 6867db96d56Sopenharmony_ci self.assertEqual(program.test, 'tests') 6877db96d56Sopenharmony_ci self.assertEqual(Loader.args, [('fish', 'eggs', 'ham')]) 6887db96d56Sopenharmony_ci 6897db96d56Sopenharmony_ci Loader.args = [] 6907db96d56Sopenharmony_ci program = TestableTestProgram() 6917db96d56Sopenharmony_ci program._do_discovery(['-s', 'fish'], Loader=Loader) 6927db96d56Sopenharmony_ci self.assertEqual(program.test, 'tests') 6937db96d56Sopenharmony_ci self.assertEqual(Loader.args, [('fish', 'test*.py', None)]) 6947db96d56Sopenharmony_ci 6957db96d56Sopenharmony_ci Loader.args = [] 6967db96d56Sopenharmony_ci program = TestableTestProgram() 6977db96d56Sopenharmony_ci program._do_discovery(['-t', 'fish'], Loader=Loader) 6987db96d56Sopenharmony_ci self.assertEqual(program.test, 'tests') 6997db96d56Sopenharmony_ci self.assertEqual(Loader.args, [('.', 'test*.py', 'fish')]) 7007db96d56Sopenharmony_ci 7017db96d56Sopenharmony_ci Loader.args = [] 7027db96d56Sopenharmony_ci program = TestableTestProgram() 7037db96d56Sopenharmony_ci program._do_discovery(['-p', 'fish'], Loader=Loader) 7047db96d56Sopenharmony_ci self.assertEqual(program.test, 'tests') 7057db96d56Sopenharmony_ci self.assertEqual(Loader.args, [('.', 'fish', None)]) 7067db96d56Sopenharmony_ci self.assertFalse(program.failfast) 7077db96d56Sopenharmony_ci self.assertFalse(program.catchbreak) 7087db96d56Sopenharmony_ci 7097db96d56Sopenharmony_ci Loader.args = [] 7107db96d56Sopenharmony_ci program = TestableTestProgram() 7117db96d56Sopenharmony_ci program._do_discovery(['-p', 'eggs', '-s', 'fish', '-v', '-f', '-c'], 7127db96d56Sopenharmony_ci Loader=Loader) 7137db96d56Sopenharmony_ci self.assertEqual(program.test, 'tests') 7147db96d56Sopenharmony_ci self.assertEqual(Loader.args, [('fish', 'eggs', None)]) 7157db96d56Sopenharmony_ci self.assertEqual(program.verbosity, 2) 7167db96d56Sopenharmony_ci self.assertTrue(program.failfast) 7177db96d56Sopenharmony_ci self.assertTrue(program.catchbreak) 7187db96d56Sopenharmony_ci 7197db96d56Sopenharmony_ci def setup_module_clash(self): 7207db96d56Sopenharmony_ci class Module(object): 7217db96d56Sopenharmony_ci __file__ = 'bar/foo.py' 7227db96d56Sopenharmony_ci sys.modules['foo'] = Module 7237db96d56Sopenharmony_ci full_path = os.path.abspath('foo') 7247db96d56Sopenharmony_ci original_listdir = os.listdir 7257db96d56Sopenharmony_ci original_isfile = os.path.isfile 7267db96d56Sopenharmony_ci original_isdir = os.path.isdir 7277db96d56Sopenharmony_ci original_realpath = os.path.realpath 7287db96d56Sopenharmony_ci 7297db96d56Sopenharmony_ci def cleanup(): 7307db96d56Sopenharmony_ci os.listdir = original_listdir 7317db96d56Sopenharmony_ci os.path.isfile = original_isfile 7327db96d56Sopenharmony_ci os.path.isdir = original_isdir 7337db96d56Sopenharmony_ci os.path.realpath = original_realpath 7347db96d56Sopenharmony_ci del sys.modules['foo'] 7357db96d56Sopenharmony_ci if full_path in sys.path: 7367db96d56Sopenharmony_ci sys.path.remove(full_path) 7377db96d56Sopenharmony_ci self.addCleanup(cleanup) 7387db96d56Sopenharmony_ci 7397db96d56Sopenharmony_ci def listdir(_): 7407db96d56Sopenharmony_ci return ['foo.py'] 7417db96d56Sopenharmony_ci def isfile(_): 7427db96d56Sopenharmony_ci return True 7437db96d56Sopenharmony_ci def isdir(_): 7447db96d56Sopenharmony_ci return True 7457db96d56Sopenharmony_ci os.listdir = listdir 7467db96d56Sopenharmony_ci os.path.isfile = isfile 7477db96d56Sopenharmony_ci os.path.isdir = isdir 7487db96d56Sopenharmony_ci if os.name == 'nt': 7497db96d56Sopenharmony_ci # ntpath.realpath may inject path prefixes when failing to 7507db96d56Sopenharmony_ci # resolve real files, so we substitute abspath() here instead. 7517db96d56Sopenharmony_ci os.path.realpath = os.path.abspath 7527db96d56Sopenharmony_ci return full_path 7537db96d56Sopenharmony_ci 7547db96d56Sopenharmony_ci def test_detect_module_clash(self): 7557db96d56Sopenharmony_ci full_path = self.setup_module_clash() 7567db96d56Sopenharmony_ci loader = unittest.TestLoader() 7577db96d56Sopenharmony_ci 7587db96d56Sopenharmony_ci mod_dir = os.path.abspath('bar') 7597db96d56Sopenharmony_ci expected_dir = os.path.abspath('foo') 7607db96d56Sopenharmony_ci msg = re.escape(r"'foo' module incorrectly imported from %r. Expected %r. " 7617db96d56Sopenharmony_ci "Is this module globally installed?" % (mod_dir, expected_dir)) 7627db96d56Sopenharmony_ci self.assertRaisesRegex( 7637db96d56Sopenharmony_ci ImportError, '^%s$' % msg, loader.discover, 7647db96d56Sopenharmony_ci start_dir='foo', pattern='foo.py' 7657db96d56Sopenharmony_ci ) 7667db96d56Sopenharmony_ci self.assertEqual(sys.path[0], full_path) 7677db96d56Sopenharmony_ci 7687db96d56Sopenharmony_ci def test_module_symlink_ok(self): 7697db96d56Sopenharmony_ci full_path = self.setup_module_clash() 7707db96d56Sopenharmony_ci 7717db96d56Sopenharmony_ci original_realpath = os.path.realpath 7727db96d56Sopenharmony_ci 7737db96d56Sopenharmony_ci mod_dir = os.path.abspath('bar') 7747db96d56Sopenharmony_ci expected_dir = os.path.abspath('foo') 7757db96d56Sopenharmony_ci 7767db96d56Sopenharmony_ci def cleanup(): 7777db96d56Sopenharmony_ci os.path.realpath = original_realpath 7787db96d56Sopenharmony_ci self.addCleanup(cleanup) 7797db96d56Sopenharmony_ci 7807db96d56Sopenharmony_ci def realpath(path): 7817db96d56Sopenharmony_ci if path == os.path.join(mod_dir, 'foo.py'): 7827db96d56Sopenharmony_ci return os.path.join(expected_dir, 'foo.py') 7837db96d56Sopenharmony_ci return path 7847db96d56Sopenharmony_ci os.path.realpath = realpath 7857db96d56Sopenharmony_ci loader = unittest.TestLoader() 7867db96d56Sopenharmony_ci loader.discover(start_dir='foo', pattern='foo.py') 7877db96d56Sopenharmony_ci 7887db96d56Sopenharmony_ci def test_discovery_from_dotted_path(self): 7897db96d56Sopenharmony_ci loader = unittest.TestLoader() 7907db96d56Sopenharmony_ci 7917db96d56Sopenharmony_ci tests = [self] 7927db96d56Sopenharmony_ci expectedPath = os.path.abspath(os.path.dirname(unittest.test.__file__)) 7937db96d56Sopenharmony_ci 7947db96d56Sopenharmony_ci self.wasRun = False 7957db96d56Sopenharmony_ci def _find_tests(start_dir, pattern): 7967db96d56Sopenharmony_ci self.wasRun = True 7977db96d56Sopenharmony_ci self.assertEqual(start_dir, expectedPath) 7987db96d56Sopenharmony_ci return tests 7997db96d56Sopenharmony_ci loader._find_tests = _find_tests 8007db96d56Sopenharmony_ci suite = loader.discover('unittest.test') 8017db96d56Sopenharmony_ci self.assertTrue(self.wasRun) 8027db96d56Sopenharmony_ci self.assertEqual(suite._tests, tests) 8037db96d56Sopenharmony_ci 8047db96d56Sopenharmony_ci 8057db96d56Sopenharmony_ci def test_discovery_from_dotted_path_builtin_modules(self): 8067db96d56Sopenharmony_ci 8077db96d56Sopenharmony_ci loader = unittest.TestLoader() 8087db96d56Sopenharmony_ci 8097db96d56Sopenharmony_ci listdir = os.listdir 8107db96d56Sopenharmony_ci os.listdir = lambda _: ['test_this_does_not_exist.py'] 8117db96d56Sopenharmony_ci isfile = os.path.isfile 8127db96d56Sopenharmony_ci isdir = os.path.isdir 8137db96d56Sopenharmony_ci os.path.isdir = lambda _: False 8147db96d56Sopenharmony_ci orig_sys_path = sys.path[:] 8157db96d56Sopenharmony_ci def restore(): 8167db96d56Sopenharmony_ci os.path.isfile = isfile 8177db96d56Sopenharmony_ci os.path.isdir = isdir 8187db96d56Sopenharmony_ci os.listdir = listdir 8197db96d56Sopenharmony_ci sys.path[:] = orig_sys_path 8207db96d56Sopenharmony_ci self.addCleanup(restore) 8217db96d56Sopenharmony_ci 8227db96d56Sopenharmony_ci with self.assertRaises(TypeError) as cm: 8237db96d56Sopenharmony_ci loader.discover('sys') 8247db96d56Sopenharmony_ci self.assertEqual(str(cm.exception), 8257db96d56Sopenharmony_ci 'Can not use builtin modules ' 8267db96d56Sopenharmony_ci 'as dotted module names') 8277db96d56Sopenharmony_ci 8287db96d56Sopenharmony_ci def test_discovery_failed_discovery(self): 8297db96d56Sopenharmony_ci loader = unittest.TestLoader() 8307db96d56Sopenharmony_ci package = types.ModuleType('package') 8317db96d56Sopenharmony_ci 8327db96d56Sopenharmony_ci def _import(packagename, *args, **kwargs): 8337db96d56Sopenharmony_ci sys.modules[packagename] = package 8347db96d56Sopenharmony_ci return package 8357db96d56Sopenharmony_ci 8367db96d56Sopenharmony_ci with unittest.mock.patch('builtins.__import__', _import): 8377db96d56Sopenharmony_ci # Since loader.discover() can modify sys.path, restore it when done. 8387db96d56Sopenharmony_ci with import_helper.DirsOnSysPath(): 8397db96d56Sopenharmony_ci # Make sure to remove 'package' from sys.modules when done. 8407db96d56Sopenharmony_ci with test.test_importlib.util.uncache('package'): 8417db96d56Sopenharmony_ci with self.assertRaises(TypeError) as cm: 8427db96d56Sopenharmony_ci loader.discover('package') 8437db96d56Sopenharmony_ci self.assertEqual(str(cm.exception), 8447db96d56Sopenharmony_ci 'don\'t know how to discover from {!r}' 8457db96d56Sopenharmony_ci .format(package)) 8467db96d56Sopenharmony_ci 8477db96d56Sopenharmony_ci 8487db96d56Sopenharmony_ciif __name__ == '__main__': 8497db96d56Sopenharmony_ci unittest.main() 850