def run(self): """ Finds and executes unit tests in the 'tests' subdir. Because TestLoader imports the tests as a module this method automatically creates/updates the 'tests/__init__.py' to import all python scripts in the 'tests' subdir. """ self.run_command('build') sys.path.insert(0, os.path.join(os.getcwd(), "build", "lib")) self.tests = [] # make sure the 'tests' subdir actually exists. if not os.path.isdir(self.tests_dir): print "ExecuteTests: <Error> 'tests' subdir not found!" else: self.find_tests() self.gen_tests_init() # create a test suite. tests = TestLoader().loadTestsFromNames([t[0] for t in self.tests]) if not self.filter is None: tests = self.filter_tests(tests) # run the test suite if it actually contains test cases. run_verbosity = 2 if self.verbose == 0: run_verbosity = 0 if tests.countTestCases() > 0: runner = TextTestRunner(verbosity=run_verbosity) runner.run(tests) else: print "ExecuteTests: <Warning> No test cases found!" sys.path.pop(0)
def run(self): """ Finds and executes unit tests in the 'tests' subdir. Because TestLoader imports the tests as a module this method automatically creates/updates the 'tests/__init__.py' to import all python scripts in the 'tests' subdir. """ self.run_command('build') sys.path.insert(0,os.path.join(os.getcwd(),"build","lib")) self.tests = [] # make sure the 'tests' subdir actually exists. if not os.path.isdir(self.tests_dir): print "ExecuteTests: <Error> 'tests' subdir not found!" else: self.find_tests() self.gen_tests_init() # create a test suite. tests = TestLoader().loadTestsFromNames([t[0] for t in self.tests]) if not self.filter is None: tests = self.filter_tests(tests) # run the test suite if it actually contains test cases. run_verbosity = 2 if self.verbose == 0: run_verbosity = 0 if tests.countTestCases() > 0: runner = TextTestRunner(verbosity=run_verbosity) runner.run(tests) else: print "ExecuteTests: <Warning> No test cases found!" sys.path.pop(0)
def run( tests_require: Optional[List[str]] = None, start_directory: Optional[ Union[str, List[str]]] = default_start_directory, buffer=False, failfast=False, verbosity=default_verbosity, exit_if_failed=True, warnings: Warnings = default_warnings_handling, ignore_warnings: List[str] = None, json=False, ) -> RunResult: """Discovers and runs unit tests for module or modules. tests_require: Dependent modules to install with `pip install` before running tests. These are modules that are used for testing but are not needed in production. pattern: Mask for the names of the python files that contain the tests. start_dir: Directory with the module, that contain all the TestCases. Can also be a list of module directories. In that case each module will be scanned separately. By default, `start_dir` is None. None value will lead to scanning `top_level_dir` for the modules. top_level_dir: Top level directory of project (defaults to current directory). None will set it to the directory containing the currently tested module. buffer: Buffer stdout and stderr during tests. failfast: Stop on first fail or error. verbosity: 0 for quiet, 2 for verbose. ignore_warnings: Allows you to hide individual warnings. If any of the listed strings is found in the warning message, the message will not be displayed. """ top_level_directory = default_top_level_dir pattern = default_pattern temp_mute = TempMute() if json else None try: def rel_to_top(p: Path) -> str: return str( p.absolute().relative_to(Path(top_level_directory).absolute())) try: if tests_require: install_requirements(tests_require) print(splitter) if start_directory is not None: # todo unittest if isinstance(start_directory, str): start_dirs = [start_directory] else: start_dirs = start_directory else: start_dirs = [str(p) for p in find_start_dirs()] suites: List[unittest.TestSuite] = [] for sd in start_dirs: suite = TestLoader().discover( top_level_dir=(top_level_directory if top_level_directory is not None else sd), start_dir=sd, pattern=pattern) print( f'Package "{rel_to_top(Path(sd))}" contains ' f'{suite.countTestCases()} tests') if suite.countTestCases() > 0: suites.append(suite) combo_suite = TestSuite(suites) with wrn.catch_warnings(record=True) as catcher: # with the default unittest, even if warnings are enabled, the # --buffer argument makes them invisible: warnings are # printed, but the output is buffered and not shown not # displayed unless the corresponding test fails # # But we want to see the warnings, even with --buffered, # until they are explicitly disabled. # # So the run(warning=None), and we handle all the warnings # manually set_warnings_filter( PythonWarningsArgs.ignore if warnings == Warnings.ignore else PythonWarningsArgs.default) result = TextTestRunner(buffer=buffer, verbosity=verbosity.value, failfast=failfast, warnings=None).run(combo_suite) caught_warnings = list(catcher) formatted_warnings = [ wrn.formatwarning(message=w.message, category=w.category, filename=w.filename, lineno=w.lineno, line=w.line) for w in caught_warnings] formatted_warnings = _remove_those_contain(formatted_warnings, ignore_warnings) if formatted_warnings: print() print(splitter) print(f"Caught {len(caught_warnings)} warnings:") for w in formatted_warnings: print() print(w) if json: assert temp_mute is not None temp_mute.unmute() print(dumps({ 'run': result.testsRun, 'skipped': len(result.skipped), 'failures': len(result.failures), 'errors': len(result.errors), 'unexpected_successes': len(result.unexpectedSuccesses), 'warnings': len(caught_warnings) if caught_warnings else 0 })) if exit_if_failed: if not result.wasSuccessful(): raise TestsError if warnings == Warnings.fail and caught_warnings: raise WarningsError return RunResult(result, caught_warnings) except NeatestError as e: if not json: print(e.message) if exit_if_failed: sys.exit(1) else: raise # alternatively we could run the tests exactly as '-m unittest' does # with unittest.TestProgram(module=None, argv) # where argv is ['python -m unittest', 'discover', ...] finally: if temp_mute: temp_mute.unmute()
#!/usr/bin/env python3 from unittest import TestLoader if __name__ == '__main__': runner = TestLoader().discover('tests') print('Running {} tests...'.format(runner.countTestCases())) runner.debug() print('All tests passed.')