def test_returnIsLoadable(self): """ Results returned by toParallelTargets should be loadable by loadTargets(), even if they aren't directly loadable through a package relative to the current working directory. """ tests_dir = tempfile.mkdtemp(dir=self.tmpdir) # No __init__.py in the directory! fh = open(os.path.join(tests_dir, "test_not_in_pkg.py"), "w") fh.write( dedent( """ import unittest class A(unittest.TestCase): def testPass(self): pass """ ) ) fh.close() # Discover stuff suite = loader.loadTargets(".") # This should resolve it to the module that's not importable from here test = loader.toParallelTargets(suite, [])[0] reloaded = loader.loadTargets(test)
def test_multiple_targets(self): "Specifying multiple targets causes them all to be tested" sub_tmpdir = tempfile.mkdtemp(dir=self.tmpdir) # pkg/__init__.py fh = open(os.path.join(sub_tmpdir, '__init__.py'), 'w') fh.write('\n') fh.close() # pkg/test/test_target1.py fh = open(os.path.join(sub_tmpdir, 'test_target1.py'), 'w') fh.write(""" import unittest class A(unittest.TestCase): def testPasses(self): pass""") fh.close() # pkg/test/test_target2.py fh = open(os.path.join(sub_tmpdir, 'test_target2.py'), 'w') fh.write(""" import unittest class A(unittest.TestCase): def testPasses(self): pass""") fh.close() # Load the tests os.chdir(self.tmpdir) pkg = os.path.basename(sub_tmpdir) tests = loader.loadTargets([pkg + '.' + 'test_target1', pkg + '.' + 'test_target2']) self.assertEqual(tests.countTestCases(), 2)
def test_partiallyGoodName(self): """ Don't crash loading module.object with existing module but not object. """ # Parent directory setup os.chdir(self.tmpdir) sub_tmpdir = tempfile.mkdtemp(dir=self.tmpdir) basename = os.path.basename(sub_tmpdir) # Child setup fh = open(os.path.join(basename, '__init__.py'), 'w') fh.write('\n') fh.close() fh = open(os.path.join(basename, 'existing_module.py'), 'w') fh.write( dedent(""" import unittest class A(unittest.TestCase): def testPass(self): pass """)) fh.close() # Load the tests module_name = basename + ".existing_module.nonexistant_object" tests = loader.loadTargets(module_name) self.assertEqual(tests, None)
def test_DottedNamePackageFromPath(self): """ Importing a package from path loads the tests. """ # Child setup tmp_subdir = tempfile.mkdtemp(dir=self.tmpdir) fh = open(os.path.join(tmp_subdir, '__init__.py'), 'w') fh.write('\n') fh.close() fh = open(os.path.join(tmp_subdir, 'test_module.py'), 'w') fh.write(dedent( """ import unittest class A(unittest.TestCase): def testPass(self): pass """)) fh.close() # Go somewhere else, but setup the path os.chdir(self.startdir) sys.path.insert(0, self.tmpdir) # Load the tests tests = loader.loadTargets(os.path.basename(tmp_subdir)) sys.path.remove(self.tmpdir) self.assertTrue(tests.countTestCases(), 1)
def test_catchProcessSIGINT(self): """ run() can catch SIGINT while running a process. """ if platform.system() == 'Windows': self.skipTest('This test is for posix-specific behavior.') # Mock the list of TestResult instances that should be stopped, # otherwise the actual TestResult that is running this test will be # told to stop when we send SIGINT sub_tmpdir = tempfile.mkdtemp(dir=self.tmpdir) saved__results = unittest.signals._results unittest.signals._results = weakref.WeakKeyDictionary() self.addCleanup(setattr, unittest.signals, '_results', saved__results) fh = open(os.path.join(sub_tmpdir, 'test_sigint.py'), 'w') fh.write(dedent( """ import os import signal import unittest class SIGINTCase(unittest.TestCase): def test00(self): os.kill({}, signal.SIGINT) """.format(os.getpid()))) fh.close() os.chdir(sub_tmpdir) tests = loadTargets('test_sigint') self.args.processes = 2 run(tests, self.stream, self.args) os.chdir(TestProcesses.startdir)
def test_DottedName(self): """ Importing a module via dotted name loads the tests. """ # Parent directory setup os.chdir(self.tmpdir) sub_tmpdir = tempfile.mkdtemp(dir=self.tmpdir) basename = os.path.basename(sub_tmpdir) # Child setup fh = open(os.path.join(basename, '__init__.py'), 'w') fh.write('\n') fh.close() fh = open(os.path.join(basename, 'test_module_dotted_name.py'), 'w') fh.write( dedent(""" import unittest class A(unittest.TestCase): def testPass(self): pass """)) fh.close() # Load the tests module_name = basename + ".test_module_dotted_name" tests = loader.loadTargets(module_name) self.assertEqual(tests.countTestCases(), 1)
def test_DirWithInit(self): """ Dir empty other than blank __init__.py returns None """ # Parent directory setup os.chdir(self.tmpdir) os.chdir('..') # Child setup target = os.path.join(self.tmpdir, '__init__.py') fh = open(target, 'w') fh.write('\n') fh.close() fh = open(os.path.join(self.tmpdir, 'test_module_with_init.py'), 'w') fh.write( dedent(""" import unittest class A(unittest.TestCase): def testPass(self): pass """)) fh.close() # Load the tests module_name = os.path.basename(self.tmpdir) tests = loader.loadTargets(module_name) self.assertEqual(tests.countTestCases(), 1)
def test_DottedNamePackageFromPath(self): """ Importing a package from path loads the tests. """ # Child setup tmp_subdir = tempfile.mkdtemp(dir=self.tmpdir) fh = open(os.path.join(tmp_subdir, '__init__.py'), 'w') fh.write('\n') fh.close() fh = open(os.path.join(tmp_subdir, 'test_module.py'), 'w') fh.write( dedent(""" import unittest class A(unittest.TestCase): def testPass(self): pass """)) fh.close() # Go somewhere else, but setup the path os.chdir(self.startdir) sys.path.insert(0, self.tmpdir) # Load the tests tests = loader.loadTargets(os.path.basename(tmp_subdir)) sys.path.remove(self.tmpdir) self.assertTrue(tests.countTestCases(), 1)
def test_DirWithInit(self): """ Dir empty other than blank __init__.py returns None """ # Parent directory setup os.chdir(self.tmpdir) os.chdir('..') # Child setup target = os.path.join(self.tmpdir, '__init__.py') fh = open(target, 'w') fh.write('\n') fh.close() fh = open(os.path.join(self.tmpdir, 'test_module_with_init.py'), 'w') fh.write(dedent( """ import unittest class A(unittest.TestCase): def testPass(self): pass """)) fh.close() # Load the tests module_name = os.path.basename(self.tmpdir) tests = loader.loadTargets(module_name) self.assertEqual(tests.countTestCases(), 1)
def test_duplicate_targets(self): """ Specifying duplicate targets does not cause duplicate loading. """ sub_tmpdir = tempfile.mkdtemp(dir=self.tmpdir) fh = open(os.path.join(sub_tmpdir, '__init__.py'), 'w') fh.write('\n') fh.close() fh = open(os.path.join(sub_tmpdir, 'test_dupe_target.py'), 'w') fh.write( dedent(""" import unittest class A(unittest.TestCase): def testPasses(self): pass """)) fh.close() os.chdir(self.tmpdir) pkg = os.path.basename(sub_tmpdir) tests = loader.loadTargets([ pkg + '.' + 'test_dupe_target', pkg + '.' + 'test_dupe_target', pkg + '.' + 'test_dupe_target' ]) self.assertEqual(tests.countTestCases(), 1)
def run_tests(self, test_labels, extra_tests=None, **kwargs): """ Run the unit tests for all the test labels in the provided list. Test labels should be dotted Python paths to test modules, test classes, or test methods. A list of 'extra' tests may also be provided; these tests will be added to the test suite. Returns the number of tests that failed. """ # Django setup self.setup_test_environment() django_db = self.setup_databases() # Green if type(test_labels) == tuple: test_labels = list(test_labels) else: raise ValueError("test_labels should be a tuple of strings") if not test_labels: test_labels = ['.'] args = mergeConfig(default_args, default_args) args.targets = test_labels stream = GreenStream(sys.stdout) suite = loadTargets(args.targets) result = run(suite, stream, args) # Django teardown self.teardown_databases(django_db) self.teardown_test_environment() return self.suite_result(suite, result)
def test_ModuleByName(self): """ A module in a package can be loaded by filename. """ os.chdir(self.tmpdir) tmp_subdir = tempfile.mkdtemp(dir=self.tmpdir) fh = open(os.path.join(tmp_subdir, '__init__.py'), 'w') fh.write('\n') fh.close() named_module = os.path.join(os.path.basename(tmp_subdir), 'named_module.py') fh = open(named_module, 'w') fh.write( dedent(""" import unittest class A(unittest.TestCase): def testPass(self): pass """)) fh.close() # Load the tests tests = loader.loadTargets(named_module) try: self.assertEqual(tests.countTestCases(), 1) except: raise finally: shutil.rmtree(tmp_subdir)
def test_partiallyGoodName(self): """ Don't crash loading module.object with existing module but not object. """ # Parent directory setup os.chdir(self.tmpdir) sub_tmpdir = tempfile.mkdtemp(dir=self.tmpdir) basename = os.path.basename(sub_tmpdir) # Child setup fh = open(os.path.join(basename, '__init__.py'), 'w') fh.write('\n') fh.close() fh = open(os.path.join(basename, 'existing_module.py'), 'w') fh.write(dedent( """ import unittest class A(unittest.TestCase): def testPass(self): pass """)) fh.close() # Load the tests module_name = basename + ".existing_module.nonexistant_object" tests = loader.loadTargets(module_name) self.assertEqual(tests, None)
def test_duplicate_targets(self): """ Specifying duplicate targets does not cause duplicate loading. """ sub_tmpdir = tempfile.mkdtemp(dir=self.tmpdir) fh = open(os.path.join(sub_tmpdir, "__init__.py"), "w") fh.write("\n") fh.close() fh = open(os.path.join(sub_tmpdir, "test_dupe_target.py"), "w") fh.write( dedent( """ import unittest class A(unittest.TestCase): def testPasses(self): pass """ ) ) fh.close() os.chdir(self.tmpdir) pkg = os.path.basename(sub_tmpdir) tests = loader.loadTargets( [pkg + "." + "test_dupe_target", pkg + "." + "test_dupe_target", pkg + "." + "test_dupe_target"] ) self.assertEqual(tests.countTestCases(), 1)
def test_ModuleByName(self): "A module in a package can be loaded by filename." os.chdir(self.tmpdir) tmp_subdir = tempfile.mkdtemp(dir=self.tmpdir) fh = open(os.path.join(tmp_subdir, '__init__.py'), 'w') fh.write('\n') fh.close() named_module = os.path.join(os.path.basename(tmp_subdir), 'named_module.py') fh = open(named_module, 'w') fh.write("""\ import unittest class A(unittest.TestCase): def testPass(self): pass """) fh.close() # Load the tests tests = loader.loadTargets(named_module) try: self.assertEqual(tests.countTestCases(), 1) except: raise finally: shutil.rmtree(tmp_subdir)
def test_multiple_targets(self): """ Specifying multiple targets causes them all to be tested. """ sub_tmpdir = tempfile.mkdtemp(dir=self.tmpdir) # pkg/__init__.py fh = open(os.path.join(sub_tmpdir, '__init__.py'), 'w') fh.write('\n') fh.close() # pkg/test/test_target1.py fh = open(os.path.join(sub_tmpdir, 'test_target1.py'), 'w') fh.write( dedent(""" import unittest class A(unittest.TestCase): def testPasses(self): pass """)) fh.close() # pkg/test/test_target2.py fh = open(os.path.join(sub_tmpdir, 'test_target2.py'), 'w') fh.write( dedent(""" import unittest class A(unittest.TestCase): def testPasses(self): pass """)) fh.close() # Load the tests os.chdir(self.tmpdir) pkg = os.path.basename(sub_tmpdir) tests = loader.loadTargets( [pkg + '.' + 'test_target1', pkg + '.' + 'test_target2']) self.assertEqual(tests.countTestCases(), 2)
def test_uncaughtException(self): """ Exceptions that escape the test framework get caught by poolRunner and reported as a failure. For example, the testtools implementation of TestCase unwisely (but deliberately) lets SystemExit exceptions through. """ global skip_testtools if skip_testtools: self.skipTest('testtools must be installed to run this test.') sub_tmpdir = tempfile.mkdtemp(dir=self.tmpdir) # pkg/__init__.py fh = open(os.path.join(sub_tmpdir, '__init__.py'), 'w') fh.write('\n') fh.close() fh = open(os.path.join(sub_tmpdir, 'test_uncaught.py'), 'w') fh.write(dedent( """ import testtools class Uncaught(testtools.TestCase): def test_uncaught(self): raise SystemExit(0) """)) fh.close() # Load the tests os.chdir(self.tmpdir) tests = loadTargets('.') self.args.processes = 2 run(tests, self.stream, self.args) os.chdir(TestProcesses.startdir) self.assertIn('FAILED', self.stream.getvalue())
def test_relativeDotDir(self): "Dotted relative path to empty directory returns None" os.chdir(self.tmpdir) os.chdir('..') target = os.path.join('.', os.path.basename(self.tmpdir)) tests = loader.loadTargets(target) self.assertTrue(tests == None)
def test_runCoverage(self): """ Running coverage in process mode doesn't crash """ try: import coverage; coverage except: self.skipTest("Coverage needs to be installed for this test") sub_tmpdir = tempfile.mkdtemp(dir=self.tmpdir) # pkg/__init__.py fh = open(os.path.join(sub_tmpdir, '__init__.py'), 'w') fh.write('\n') fh.close() fh = open(os.path.join(sub_tmpdir, 'test_coverage.py'), 'w') fh.write(dedent( """ import unittest class A(unittest.TestCase): def testPasses(self): pass""")) fh.close() # Load the tests os.chdir(self.tmpdir) tests = loadTargets('.') self.args.processes = 2 self.args.run_coverage = True self.args.cov = MagicMock() run(tests, self.stream, self.args, testing=True) os.chdir(TestProcesses.startdir) self.assertIn('OK', self.stream.getvalue())
def test_runCoverage(self): """ Running coverage in process mode doesn't crash """ sub_tmpdir = tempfile.mkdtemp(dir=self.tmpdir) # pkg/__init__.py fh = open(os.path.join(sub_tmpdir, '__init__.py'), 'w') fh.write('\n') fh.close() fh = open(os.path.join(sub_tmpdir, 'test_coverage.py'), 'w') fh.write(dedent( """ import unittest class A(unittest.TestCase): def testPasses(self): pass""")) fh.close() # Load the tests os.chdir(self.tmpdir) tests = loadTargets('.') self.args.processes = 2 self.args.run_coverage = True run(tests, self.stream, self.args) os.chdir(TestProcesses.startdir) self.assertIn('OK', self.stream.getvalue())
def test_emptyDirDot(self): """ '.' while in an empty directory returns None """ os.chdir(self.tmpdir) tests = loader.loadTargets('.') self.assertTrue(tests is None)
def test_DottedName(self): """ Importing a module via dotted name loads the tests. """ # Parent directory setup os.chdir(self.tmpdir) sub_tmpdir = tempfile.mkdtemp(dir=self.tmpdir) basename = os.path.basename(sub_tmpdir) # Child setup fh = open(os.path.join(basename, '__init__.py'), 'w') fh.write('\n') fh.close() fh = open(os.path.join(basename, 'test_module_dotted_name.py'), 'w') fh.write(dedent( """ import unittest class A(unittest.TestCase): def testPass(self): pass """)) fh.close() # Load the tests module_name = basename + ".test_module_dotted_name" tests = loader.loadTargets(module_name) self.assertEqual(tests.countTestCases(), 1)
def test_emptyDirRelative(self): """ Relative path to empty directory returns None """ os.chdir(self.tmpdir) os.chdir('..') tests = loader.loadTargets(os.path.dirname(self.tmpdir)) self.assertEqual(tests, None)
def test_relativeDotDir(self): """ Dotted relative path to empty directory returns None """ os.chdir(self.tmpdir) os.chdir('..') target = os.path.join('.', os.path.basename(self.tmpdir)) tests = loader.loadTargets(target) self.assertTrue(tests is None)
def test_collisionProtection(self): """ If tempfile.gettempdir() is used for dir, using same testfile name will not collide. """ sub_tmpdir = tempfile.mkdtemp(dir=self.tmpdir) # Child setup # pkg/__init__.py fh = open(os.path.join(sub_tmpdir, '__init__.py'), 'w') fh.write('\n') fh.close() # pkg/target_module.py fh = open(os.path.join(sub_tmpdir, 'some_module.py'), 'w') fh.write('a = 1\n') fh.close() # pkg/test/__init__.py os.mkdir(os.path.join(sub_tmpdir, 'test')) fh = open(os.path.join(sub_tmpdir, 'test', '__init__.py'), 'w') fh.write('\n') fh.close() # pkg/test/test_target_module.py fh = open(os.path.join(sub_tmpdir, 'test', 'test_some_module.py'), 'w') fh.write(dedent( """ import os import tempfile import unittest import {}.some_module class A(unittest.TestCase): def setUp(self): self.tmpdir = tempfile.gettempdir() self.filename = os.path.join(tempfile.gettempdir(), 'file.txt') def testOne(self): for msg in [str(x) for x in range(100)]: fh = open(self.filename, 'w') fh.write(msg) fh.close() self.assertEqual(msg, open(self.filename).read()) def testTwo(self): for msg in [str(x) for x in range(100,200)]: fh = open(self.filename, 'w') fh.write(msg) fh.close() self.assertEqual(msg, open(self.filename).read()) """.format(os.path.basename(sub_tmpdir)))) fh.close() # Load the tests os.chdir(self.tmpdir) tests = loadTargets('.') self.args.processes = 2 self.args.termcolor = False try: run(tests, self.stream, self.args) except KeyboardInterrupt: os.kill(os.getpid(), signal.SIGINT) os.chdir(TestProcesses.startdir) self.assertIn('OK', self.stream.getvalue())
def test_collisionProtection(self): """ If tempfile.gettempdir() is used for dir, using same testfile name will not collide. """ sub_tmpdir = tempfile.mkdtemp(dir=self.tmpdir) # Child setup # pkg/__init__.py fh = open(os.path.join(sub_tmpdir, '__init__.py'), 'w') fh.write('\n') fh.close() # pkg/target_module.py fh = open(os.path.join(sub_tmpdir, 'some_module.py'), 'w') fh.write('a = 1\n') fh.close() # pkg/test/__init__.py os.mkdir(os.path.join(sub_tmpdir, 'test')) fh = open(os.path.join(sub_tmpdir, 'test', '__init__.py'), 'w') fh.write('\n') fh.close() # pkg/test/test_target_module.py fh = open(os.path.join(sub_tmpdir, 'test', 'test_some_module.py'), 'w') fh.write( dedent(""" import os import tempfile import unittest import {}.some_module class A(unittest.TestCase): def setUp(self): self.tmpdir = tempfile.gettempdir() self.filename = os.path.join(tempfile.gettempdir(), 'file.txt') def testOne(self): for msg in [str(x) for x in range(100)]: fh = open(self.filename, 'w') fh.write(msg) fh.close() self.assertEqual(msg, open(self.filename).read()) def testTwo(self): for msg in [str(x) for x in range(100,200)]: fh = open(self.filename, 'w') fh.write(msg) fh.close() self.assertEqual(msg, open(self.filename).read()) """.format(os.path.basename(sub_tmpdir)))) fh.close() # Load the tests os.chdir(self.tmpdir) tests = loadTargets('.') self.args.processes = 2 self.args.termcolor = False try: run(tests, self.stream, self.args) except KeyboardInterrupt: os.kill(os.getpid(), signal.SIGINT) os.chdir(TestProcesses.startdir) self.assertIn('OK', self.stream.getvalue())
def poolRunner(test_name, coverage_number=None, omit_patterns=[]): "I am the function that pool worker subprocesses run. I run one unit test." # Each pool worker gets his own temp directory, to avoid having tests that # are used to taking turns using the same temp file name from interfering # with eachother. So long as the test doesn't use a hard-coded temp # directory, anyway. saved_tempdir = tempfile.tempdir tempfile.tempdir = tempfile.mkdtemp() # Each pool starts its own coverage, later combined by the main process. if coverage_number and coverage: cov = coverage.coverage( data_file='.coverage.{}_{}'.format( coverage_number, random.randint(0, 10000)), omit=omit_patterns) cov.start() # Create a structure to return the results of this one test result = ProtoTestResult() test = None try: test = loadTargets(test_name) except: err = sys.exc_info() t = ProtoTest() t.module = 'green.loader' t.class_name = 'N/A' t.description = 'Green encountered an error loading the unit test.' t.method_name = 'poolRunner' result.addError(t, err) try: test.run(result) except: # Some frameworks like testtools record the error AND THEN let it # through to crash things. So we only need to manufacture another error # if the underlying framework didn't, but either way we don't want to # crash. if not result.errors: err = sys.exc_info() t = ProtoTest() t.module = 'green.runner' t.class_name = 'N/A' t.description = 'Green encountered an exception not caught by the underlying test framework.' t.method_name = 'poolRunner' result.addError(t, err) # Finish coverage if coverage_number and coverage: cov.stop() cov.save() # Restore the state of the temp directory shutil.rmtree(tempfile.tempdir) tempfile.tempdir = saved_tempdir return result
def test_file_pattern(self): """ Specifying a file pattern causes only matching files to be loaded """ sub_tmpdir = tempfile.mkdtemp(dir=self.tmpdir) # pkg/__init__.py fh = open(os.path.join(sub_tmpdir, "__init__.py"), "w") fh.write("\n") fh.close() # pkg/test/target1_tests.py fh = open(os.path.join(sub_tmpdir, "target1_tests.py"), "w") fh.write( dedent( """ import unittest class A(unittest.TestCase): def testPasses(self): pass """ ) ) fh.close() # pkg/test/target2_tests.py fh = open(os.path.join(sub_tmpdir, "target2_tests.py"), "w") fh.write( dedent( """ import unittest class A(unittest.TestCase): def testPasses(self): pass """ ) ) fh.close() # pkg/test/test_target999.py: NOT a match. fh = open(os.path.join(sub_tmpdir, "test_target999.py"), "w") fh.write( dedent( """ import unittest class A(unittest.TestCase): def testPasses(self): pass """ ) ) fh.close() # Load the tests os.chdir(self.tmpdir) pkg = os.path.basename(sub_tmpdir) tests = loader.loadTargets(pkg, file_pattern="*_tests.py") self.assertEqual(tests.countTestCases(), 2)
def test_returnIsLoadable(self): """ Results returned by toParallelTargets should be loadable by loadTargets(), even if they aren't directly loadable through a package relative to the current working directory. """ tests_dir = tempfile.mkdtemp(dir=self.tmpdir) # No __init__.py in the directory! fh = open(os.path.join(tests_dir, 'test_not_in_pkg.py'), 'w') fh.write( dedent(""" import unittest class A(unittest.TestCase): def testPass(self): pass """)) fh.close() # Discover stuff suite = loader.loadTargets('.') # This should resolve it to the module that's not importable from here test = loader.toParallelTargets(suite, [])[0] loader.loadTargets(test)
def test_explicit_filename_error(self): """ Loading a module by name with a syntax error produces a failure, not a silent absence of its tests. """ sub_tmpdir = tempfile.mkdtemp(dir=self.tmpdir) fh = open(os.path.join(sub_tmpdir, 'mod_with_import_error.py'), 'w') fh.write('this is a syntax error') fh.close() os.chdir(sub_tmpdir) tests = loader.loadTargets('mod_with_import_error.py') self.assertEqual(tests.countTestCases(), 1)
def test_collisionProtection(self): """ If tempfile.gettempdir() is used for dir, using same testfile name will not collide. """ sub_tmpdir = tempfile.mkdtemp(dir=self.tmpdir) # Child setup # pkg/__init__.py fh = open(os.path.join(sub_tmpdir, '__init__.py'), 'w') fh.write('\n') fh.close() # pkg/target_module.py fh = open(os.path.join(sub_tmpdir, 'some_module.py'), 'w') fh.write('a = 1\n') fh.close() # pkg/test/__init__.py os.mkdir(os.path.join(sub_tmpdir, 'test')) fh = open(os.path.join(sub_tmpdir, 'test', '__init__.py'), 'w') fh.write('\n') fh.close() # pkg/test/test_target_module.py fh = open(os.path.join(sub_tmpdir, 'test', 'test_some_module.py'), 'w') fh.write("""\ import os import tempfile import unittest import {}.some_module class A(unittest.TestCase): def setUp(self): self.tmpdir = tempfile.gettempdir() self.filename = os.path.join(tempfile.gettempdir(), 'file.txt') def testOne(self): for msg in [str(x) for x in range(100)]: fh = open(self.filename, 'w') fh.write(msg) fh.close() self.assertEqual(msg, open(self.filename).read()) def testTwo(self): for msg in [str(x) for x in range(100,200)]: fh = open(self.filename, 'w') fh.write(msg) fh.close() self.assertEqual(msg, open(self.filename).read()) """.format(os.path.basename(sub_tmpdir))) fh.close() # Load the tests os.chdir(self.tmpdir) tests = loadTargets('.') gtr = GreenTestRunner(self.stream, subprocesses=2, termcolor=False) gtr.run(tests) self.assertIn('OK', self.stream.getvalue())
def test_MalformedModuleByName(self): """ Importing malformed module by name creates test that raises ImportError. """ fh = open(os.path.join(self.tmpdir, "__init__.py"), "w") fh.write("\n") fh.close() malformed_module = os.path.join(os.path.basename(self.tmpdir), "malformed_module.py") fh = open(malformed_module, "w") fh.write("This is a malformed module.") fh.close() # Load the tests tests = loader.loadTargets(malformed_module) self.assertEqual(tests.countTestCases(), 1) test = tests._tests[0]._tests[0] test_method = getattr(test, test._testMethodName) self.assertRaises(ImportError, test_method)
def test_MalformedModuleByName(self): """ Don't crash discovering tests in package with module with SyntaxError. """ fh = open(os.path.join(self.tmpdir, '__init__.py'), 'w') fh.write('\n') fh.close() malformed_module = os.path.join(os.path.basename(self.tmpdir), 'malformed_module.py') fh = open(malformed_module, 'w') fh.write("This is a malformed module.") fh.close() # Load the tests tests = loader.loadTargets(malformed_module) self.assertEqual(tests.countTestCases(), 1) test = tests._tests[0]._tests[0] test_method = getattr(test, test._testMethodName) self.assertRaises(ImportError, test_method)
def test_MalformedModuleByName(self): """ Importing malformed module by name creates test that raises ImportError. """ fh = open(os.path.join(self.tmpdir, '__init__.py'), 'w') fh.write('\n') fh.close() malformed_module = os.path.join(os.path.basename(self.tmpdir), 'malformed_module.py') fh = open(malformed_module, 'w') fh.write("This is a malformed module.") fh.close() # Load the tests tests = loader.loadTargets(malformed_module) self.assertEqual(tests.countTestCases(), 1) test = tests._tests[0]._tests[0] test_method = getattr(test, test._testMethodName) self.assertRaises(ImportError, test_method)
def test_file_pattern(self): """ Specifying a file pattern causes only matching files to be loaded """ sub_tmpdir = tempfile.mkdtemp(dir=self.tmpdir) # pkg/__init__.py fh = open(os.path.join(sub_tmpdir, '__init__.py'), 'w') fh.write('\n') fh.close() # pkg/test/target1_tests.py fh = open(os.path.join(sub_tmpdir, 'target1_tests.py'), 'w') fh.write( dedent(""" import unittest class A(unittest.TestCase): def testPasses(self): pass """)) fh.close() # pkg/test/target2_tests.py fh = open(os.path.join(sub_tmpdir, 'target2_tests.py'), 'w') fh.write( dedent(""" import unittest class A(unittest.TestCase): def testPasses(self): pass """)) fh.close() # pkg/test/test_target999.py: NOT a match. fh = open(os.path.join(sub_tmpdir, 'test_target999.py'), 'w') fh.write( dedent(""" import unittest class A(unittest.TestCase): def testPasses(self): pass """)) fh.close() # Load the tests os.chdir(self.tmpdir) pkg = os.path.basename(sub_tmpdir) tests = loader.loadTargets(pkg, file_pattern='*_tests.py') self.assertEqual(tests.countTestCases(), 2)
def test_BigDirWithAbsoluteImports(self): """ Big dir discovers tests and doesn't crash on absolute import """ sub_tmpdir = tempfile.mkdtemp(dir=self.tmpdir) pkg_name = os.path.basename(sub_tmpdir) # Child setup # pkg/__init__.py fh = open(os.path.join(sub_tmpdir, "__init__.py"), "w") fh.write("\n") fh.close() # pkg/target_module.py fh = open(os.path.join(sub_tmpdir, "target_module.py"), "w") fh.write("a = 1\n") fh.close() # pkg/test/__init__.py os.mkdir(os.path.join(sub_tmpdir, "test")) fh = open(os.path.join(sub_tmpdir, "test", "__init__.py"), "w") fh.write("\n") fh.close() # pkg/test/test_target_module.py fh = open(os.path.join(sub_tmpdir, "test", "test_target_module.py"), "w") fh.write( dedent( """ import unittest import {}.target_module class A(unittest.TestCase): def testPass(self): pass """.format( pkg_name ) ) ) fh.close() # Load the tests os.chdir(self.tmpdir) test_suite = loader.loadTargets(pkg_name) self.assertEqual(test_suite.countTestCases(), 1) # Dotted name should start with the package! self.assertEqual( pkg_name + ".test.test_target_module.A.testPass", loader.toProtoTestList(test_suite)[0].dotted_name )
def test_failedSaysSo(self): """ A failing test case causes the whole run to report 'FAILED' """ sub_tmpdir = tempfile.mkdtemp(dir=self.tmpdir) fh = open(os.path.join(sub_tmpdir, 'test_failed.py'), 'w') fh.write(""" import unittest class Failed(unittest.TestCase): def test01(self): self.assertTrue(False) """.format(os.getpid())) fh.close() os.chdir(sub_tmpdir) tests = loadTargets('test_failed') result = run(tests, self.stream, self.args) os.chdir(self.startdir) self.assertEqual(result.testsRun, 1) self.assertIn('FAILED', self.stream.getvalue())
def test_badTest(self): """ Bad syntax in a testfile is caught as a test error. """ sub_tmpdir = tempfile.mkdtemp(dir=self.tmpdir) # pkg/__init__.py fh = open(os.path.join(sub_tmpdir, '__init__.py'), 'w') fh.write('\n') fh.close() # pkg/test/test_target_module.py fh = open(os.path.join(sub_tmpdir, 'test_bad_syntax.py'), 'w') fh.write("aoeu") fh.close() # Load the tests os.chdir(self.tmpdir) tests = loadTargets('.') self.args.processes = 2 os.chdir(TestProcesses.startdir) self.assertRaises(ImportError, run, tests, self.stream, self.args)
def test_duplicate_targets(self): "Specifying duplicate targets does not cause duplicate loading." sub_tmpdir = tempfile.mkdtemp(dir=self.tmpdir) fh = open(os.path.join(sub_tmpdir, '__init__.py'), 'w') fh.write('\n') fh.close() fh = open(os.path.join(sub_tmpdir, 'test_dupe_target.py'), 'w') fh.write(""" import unittest class A(unittest.TestCase): def testPasses(self): pass""") fh.close() os.chdir(self.tmpdir) pkg = os.path.basename(sub_tmpdir) tests = loader.loadTargets([pkg + '.' + 'test_dupe_target', pkg + '.' + 'test_dupe_target', pkg + '.' + 'test_dupe_target']) self.assertEqual(tests.countTestCases(), 1)
def test_warnings(self): """ setting warnings='always' doesn't crash """ self.args.warnings = 'always' sub_tmpdir = tempfile.mkdtemp(dir=self.tmpdir) fh = open(os.path.join(sub_tmpdir, 'test_warnings.py'), 'w') fh.write(""" import unittest class Warnings(unittest.TestCase): def test01(self): pass """.format(os.getpid())) fh.close() os.chdir(sub_tmpdir) tests = loadTargets('test_warnings') result = run(tests, self.stream, self.args) os.chdir(self.startdir) self.assertEqual(result.testsRun, 1) self.assertIn('OK', self.stream.getvalue())
def test_systemExit(self): """ Raising a SystemExit gets caught and reported. """ sub_tmpdir = tempfile.mkdtemp(dir=self.tmpdir) fh = open(os.path.join(sub_tmpdir, 'test_systemexit.py'), 'w') fh.write(""" import unittest class SystemExitCase(unittest.TestCase): def test00(self): raise SystemExit(1) def test01(self): pass """.format(os.getpid())) fh.close() os.chdir(sub_tmpdir) tests = loadTargets('test_systemexit') result = run(tests, self.stream, self.args) os.chdir(self.startdir) self.assertEqual(result.testsRun, 2)
def test_failedSaysSo(self): """ A failing test case causes the whole run to report 'FAILED' """ sub_tmpdir = tempfile.mkdtemp(dir=self.tmpdir) fh = open(os.path.join(sub_tmpdir, 'test_failed.py'), 'w') fh.write(dedent( """ import unittest class Failed(unittest.TestCase): def test01(self): self.assertTrue(False) """.format(os.getpid()))) fh.close() os.chdir(sub_tmpdir) tests = loadTargets('test_failed') result = run(tests, self.stream, self.args) os.chdir(self.startdir) self.assertEqual(result.testsRun, 1) self.assertIn('FAILED', self.stream.getvalue())
def poolRunner(test_name, coverage_number=None, omit=[]): "I am the function that pool worker subprocesses run. I run one unit test." # Each pool worker gets his own temp directory, to avoid having tests that # are used to taking turns using the same temp file name from interfering # with eachother. So long as the test doesn't use a hard-coded temp # directory, anyway. saved_tempdir = tempfile.tempdir tempfile.tempdir = tempfile.mkdtemp() # Each pool starts its own coverage, later combined by the main process. if coverage_number and coverage: cov = coverage.coverage( data_file='.coverage.{}_{}'.format( coverage_number, random.randint(0, 10000)), omit=omit) cov.start() # Create a structure to return the results of this one test result = ProtoTestResult() test = None try: test = loadTargets(test_name) test.run(result) except: err = sys.exc_info() t = ProtoTest() t.module = 'green.runner' t.class_name = 'N/A' t.description = 'Green encountered an error loading the unit test itself.' t.method_name = 'poolRunner' result.addError(t, err) # Finish coverage if coverage_number and coverage: cov.stop() cov.save() # Restore the state of the temp directory shutil.rmtree(tempfile.tempdir) tempfile.tempdir = saved_tempdir return result
def test_warnings(self): """ setting warnings='always' doesn't crash """ self.args.warnings = 'always' sub_tmpdir = tempfile.mkdtemp(dir=self.tmpdir) fh = open(os.path.join(sub_tmpdir, 'test_warnings.py'), 'w') fh.write(dedent( """ import unittest class Warnings(unittest.TestCase): def test01(self): pass """.format(os.getpid()))) fh.close() os.chdir(sub_tmpdir) tests = loadTargets('test_warnings') result = run(tests, self.stream, self.args) os.chdir(self.startdir) self.assertEqual(result.testsRun, 1) self.assertIn('OK', self.stream.getvalue())
def test_systemExit(self): """ Raising a SystemExit gets caught and reported. """ sub_tmpdir = tempfile.mkdtemp(dir=self.tmpdir) fh = open(os.path.join(sub_tmpdir, 'test_systemexit.py'), 'w') fh.write(dedent( """ import unittest class SystemExitCase(unittest.TestCase): def test00(self): raise SystemExit(1) def test01(self): pass """.format(os.getpid()))) fh.close() os.chdir(sub_tmpdir) tests = loadTargets('test_systemexit') result = run(tests, self.stream, self.args) os.chdir(self.startdir) self.assertEqual(result.testsRun, 2)
def test_BigDirWithAbsoluteImports(self): """ Big dir discovers tests and doesn't crash on absolute import """ sub_tmpdir = tempfile.mkdtemp(dir=self.tmpdir) pkg_name = os.path.basename(sub_tmpdir) # Child setup # pkg/__init__.py fh = open(os.path.join(sub_tmpdir, '__init__.py'), 'w') fh.write('\n') fh.close() # pkg/target_module.py fh = open(os.path.join(sub_tmpdir, 'target_module.py'), 'w') fh.write('a = 1\n') fh.close() # pkg/test/__init__.py os.mkdir(os.path.join(sub_tmpdir, 'test')) fh = open(os.path.join(sub_tmpdir, 'test', '__init__.py'), 'w') fh.write('\n') fh.close() # pkg/test/test_target_module.py fh = open(os.path.join(sub_tmpdir, 'test', 'test_target_module.py'), 'w') fh.write( dedent(""" import unittest import {}.target_module class A(unittest.TestCase): def testPass(self): pass """.format(pkg_name))) fh.close() # Load the tests os.chdir(self.tmpdir) test_suite = loader.loadTargets(pkg_name) self.assertEqual(test_suite.countTestCases(), 1) # Dotted name should start with the package! self.assertEqual(pkg_name + '.test.test_target_module.A.testPass', loader.toProtoTestList(test_suite)[0].dotted_name)
def test_failfast(self): """ failfast causes the testing to stop after the first failure. """ sub_tmpdir = tempfile.mkdtemp(dir=self.tmpdir) fh = open(os.path.join(sub_tmpdir, 'test_failfast.py'), 'w') fh.write(dedent( """ import unittest class SIGINTCase(unittest.TestCase): def test00(self): raise Exception def test01(self): pass """.format(os.getpid()))) fh.close() os.chdir(sub_tmpdir) tests = loadTargets('test_failfast') self.args.failfast = True result = run(tests, self.stream, self.args) os.chdir(self.startdir) self.assertEqual(result.testsRun, 1)
def test_verbose3(self): """ verbose=3 causes version output, and an empty test case passes. """ self.args.verbose = 3 sub_tmpdir = tempfile.mkdtemp(dir=self.tmpdir) fh = open(os.path.join(sub_tmpdir, 'test_verbose3.py'), 'w') fh.write(dedent( """ import unittest class Verbose3(unittest.TestCase): def test01(self): pass """.format(os.getpid()))) fh.close() os.chdir(sub_tmpdir) tests = loadTargets('test_verbose3') result = run(tests, self.stream, self.args) os.chdir(self.startdir) self.assertEqual(result.testsRun, 1) self.assertIn('Green', self.stream.getvalue()) self.assertIn('OK', self.stream.getvalue())
def run_tests(self, test_labels, extra_tests=None, **kwargs): """ Run the unit tests for all the test labels in the provided list. Test labels should be dotted Python paths to test modules, test classes, or test methods. A list of 'extra' tests may also be provided; these tests will be added to the test suite. Returns the number of tests that failed. """ # Django setup self.setup_test_environment() django_db = self.setup_databases() # Green if type(test_labels) == tuple: test_labels = list(test_labels) else: raise ValueError("test_labels should be a tuple of strings") if not test_labels: test_labels = ['.'] args = mergeConfig(Namespace()) if int(self.verbose) in (1,2,3): args.verbose = int(self.verbose) args.targets = test_labels stream = GreenStream(sys.stdout) suite = loadTargets(args.targets) if not suite: suite = GreenTestSuite() result = run(suite, stream, args) # Django teardown self.teardown_databases(django_db) self.teardown_test_environment() return self.suite_result(suite, result)
def test_detectNumProcesses(self): """ args.processes = 0 causes auto-detection of number of processes. """ sub_tmpdir = tempfile.mkdtemp(dir=self.tmpdir) # pkg/__init__.py fh = open(os.path.join(sub_tmpdir, '__init__.py'), 'w') fh.write('\n') fh.close() fh = open(os.path.join(sub_tmpdir, 'test_autoprocesses.py'), 'w') fh.write(dedent( """ import unittest class A(unittest.TestCase): def testPasses(self): pass""")) fh.close() # Load the tests os.chdir(self.tmpdir) tests = loadTargets('.') self.args.processes = 0 run(tests, self.stream, self.args) os.chdir(TestProcesses.startdir) self.assertIn('OK', self.stream.getvalue())
def main(testing=False): args = config.parseArguments() args = config.mergeConfig(args, testing) if args.shouldExit: return args.exitCode # Clear out all the passed-in-options just in case someone tries to run a # test that assumes sys.argv is clean. I can't guess at the script name # that they want, though, so we'll just leave ours. sys.argv = sys.argv[:1] # Set up our various main objects from green.loader import loadTargets from green.runner import run from green.output import GreenStream, debug import green.output from green.suite import GreenTestSuite GreenTestSuite.args = args if args.debug: green.output.debug_level = args.debug stream = GreenStream(sys.stdout, disable_windows=args.disable_windows) # Location of shell completion file if args.completion_file: print(os.path.join(os.path.dirname(__file__), 'shell_completion.sh')) return 0 # Argument-completion for bash and zsh (for test-target completion) if args.completions: from green.loader import getCompletions print(getCompletions(args.targets)) return 0 # Option-completion for bash and zsh if args.options: print('\n'.join(sorted(args.store_opt.options))) return 0 # Add debug logging for stuff that happened before this point here if config.files_loaded: debug("Loaded config file(s): {}".format( ', '.join(config.files_loaded))) # Discover/Load the test suite if testing: test_suite = None else: # pragma: no cover test_suite = loadTargets(args.targets, file_pattern = args.file_pattern) # We didn't even load 0 tests... if not test_suite: debug( "No test loading attempts succeeded. Created an empty test suite.") test_suite = GreenTestSuite() # Actually run the test_suite result = run(test_suite, stream, args, testing) return(int(not result.wasSuccessful()))
def poolRunner(target, queue, coverage_number=None, omit_patterns=[]): # pragma: no cover """ I am the function that pool worker processes run. I run one unit test. """ # Each pool worker gets his own temp directory, to avoid having tests that # are used to taking turns using the same temp file name from interfering # with eachother. So long as the test doesn't use a hard-coded temp # directory, anyway. saved_tempdir = tempfile.tempdir tempfile.tempdir = tempfile.mkdtemp() def cleanup(): # Restore the state of the temp directory if sys.version_info[0] == 2: # pragma: no cover shutil.rmtree(tempfile.tempdir, ignore_errors=True) tempfile.tempdir = saved_tempdir queue.put(None) # Finish coverage if coverage_number and coverage: cov.stop() cov.save() # Each pool starts its own coverage, later combined by the main process. if coverage_number and coverage: cov = coverage.coverage(data_file='.coverage.{}_{}'.format( coverage_number, random.randint(0, 10000)), omit=omit_patterns) cov._warn_no_data = False cov.start() # What to do each time an individual test is started already_sent = set() def start_callback(test): # Let the main process know what test we are starting test = proto_test(test) if test not in already_sent: queue.put(test) already_sent.add(test) def finalize_callback(test_result): # Let the main process know what happened with the test run queue.put(test_result) result = ProtoTestResult(start_callback, finalize_callback) test = None try: test = loadTargets(target) except: err = sys.exc_info() t = ProtoTest() t.module = 'green.loader' t.class_name = 'N/A' t.description = 'Green encountered an error loading the unit test.' t.method_name = 'poolRunner' result.startTest(t) result.addError(t, err) result.stopTest(t) queue.put(result) cleanup() return if getattr(test, 'run', False): # Loading was successful, lets do this try: test.run(result) # If your class setUpClass(self) method crashes, the test doesn't # raise an exception, but it does add an entry to errors. Some # other things add entries to errors as well, but they all call the # finalize callback. if result and (not result.finalize_callback_called) and getattr( result, 'errors', False): queue.put(test) queue.put(result) except: # Some frameworks like testtools record the error AND THEN let it # through to crash things. So we only need to manufacture another # error if the underlying framework didn't, but either way we don't # want to crash. if result.errors: queue.put(result) else: err = sys.exc_info() result.startTest(test) result.addError(test, err) result.stopTest(test) queue.put(result) else: # loadTargets() returned an object without a run() method, probably # None description = ('Test loader returned an un-runnable object. Is "{}" ' 'importable from your current location? Maybe you ' 'forgot an __init__.py in your directory? Unrunnable ' 'object looks like: {} of type {} with dir {}'.format( target, str(test), type(test), dir(test))) err = (TypeError, TypeError(description), None) t = ProtoTest() target_list = target.split('.') t.module = '.'.join( target_list[:-2]) if len(target_list) > 1 else target t.class_name = target.split( '.')[-2] if len(target_list) > 1 else 'UnknownClass' t.description = description t.method_name = target.split( '.')[-1] if len(target_list) > 1 else 'unknown_method' result.startTest(t) result.addError(t, err) result.stopTest(t) queue.put(result) cleanup()
def test_emptyDirAbsolute(self): """ Absolute path to empty directory returns None """ tests = loader.loadTargets(self.tmpdir) self.assertTrue(tests is None)