def run_coverage(report_method, **kwargs): """ Run a coverage method against the test suite """ from coverage import coverage as _coverage # Exclude third-party modules from coverage calculations. files = list(path('app').walkfiles('*.py')) # start the coverage recording c = _coverage(source=files) c.start() test() # create the report c.stop() getattr(c, report_method)(include=files, **kwargs) c.erase()
def main(): from optparse import OptionParser parser = OptionParser() parser.add_option("--no-cleanup", dest="cleanup_workdir", action="store_false", default=True, help="do not delete the generated C files (allows passing --no-cython on next run)") parser.add_option("--no-cleanup-sharedlibs", dest="cleanup_sharedlibs", action="store_false", default=True, help="do not delete the generated shared libary files (allows manual module experimentation)") parser.add_option("--no-cython", dest="with_cython", action="store_false", default=True, help="do not run the Cython compiler, only the C compiler") parser.add_option("--no-c", dest="use_c", action="store_false", default=True, help="do not test C compilation") parser.add_option("--no-cpp", dest="use_cpp", action="store_false", default=True, help="do not test C++ compilation") parser.add_option("--no-unit", dest="unittests", action="store_false", default=True, help="do not run the unit tests") parser.add_option("--no-doctest", dest="doctests", action="store_false", default=True, help="do not run the doctests") parser.add_option("--no-file", dest="filetests", action="store_false", default=True, help="do not run the file based tests") parser.add_option("--no-pyregr", dest="pyregr", action="store_false", default=True, help="do not run the regression tests of CPython in tests/pyregr/") parser.add_option("--cython-only", dest="cython_only", action="store_true", default=False, help="only compile pyx to c, do not run C compiler or run the tests") parser.add_option("--no-refnanny", dest="with_refnanny", action="store_false", default=True, help="do not regression test reference counting") parser.add_option("--no-fork", dest="fork", action="store_false", default=True, help="do not fork to run tests") parser.add_option("--sys-pyregr", dest="system_pyregr", action="store_true", default=False, help="run the regression tests of the CPython installation") parser.add_option("-x", "--exclude", dest="exclude", action="append", metavar="PATTERN", help="exclude tests matching the PATTERN") parser.add_option("-C", "--coverage", dest="coverage", action="store_true", default=False, help="collect source coverage data for the Compiler") parser.add_option("--coverage-xml", dest="coverage_xml", action="store_true", default=False, help="collect source coverage data for the Compiler in XML format") parser.add_option("-A", "--annotate", dest="annotate_source", action="store_true", default=True, help="generate annotated HTML versions of the test source files") parser.add_option("--no-annotate", dest="annotate_source", action="store_false", help="do not generate annotated HTML versions of the test source files") parser.add_option("-v", "--verbose", dest="verbosity", action="count", default=0, help="display test progress, pass twice to print test names") parser.add_option("-T", "--ticket", dest="tickets", action="append", help="a bug ticket number to run the respective test in 'tests/*'") parser.add_option("-3", dest="language_level", action="store_const", const=3, default=2, help="set language level to Python 3 (useful for running the CPython regression tests)'") parser.add_option("--xml-output", dest="xml_output_dir", metavar="DIR", help="write test results in XML to directory DIR") parser.add_option("--exit-ok", dest="exit_ok", default=False, action="store_true", help="exit without error code even on test failures") options, cmd_args = parser.parse_args() DISTDIR = os.path.join(os.getcwd(), os.path.dirname(sys.argv[0])) ROOTDIR = os.path.join(DISTDIR, 'tests') WORKDIR = os.path.join(os.getcwd(), 'BUILD') if sys.version_info[0] >= 3: options.doctests = False if options.with_cython: try: # try if Cython is installed in a Py3 version import Cython.Compiler.Main except Exception: # back out anything the import process loaded, then # 2to3 the Cython sources to make them re-importable cy_modules = [ name for name in sys.modules if name == 'Cython' or name.startswith('Cython.') ] for name in cy_modules: del sys.modules[name] # hasn't been refactored yet - do it now cy3_dir = os.path.join(WORKDIR, 'Cy3') if sys.version_info >= (3,1): refactor_for_py3(DISTDIR, cy3_dir) elif os.path.isdir(cy3_dir): sys.path.insert(0, cy3_dir) else: options.with_cython = False WITH_CYTHON = options.with_cython if options.coverage or options.coverage_xml: if not WITH_CYTHON: options.coverage = options.coverage_xml = False else: from coverage import coverage as _coverage coverage = _coverage(branch=True) coverage.erase() coverage.start() if WITH_CYTHON: global CompilationOptions, pyrex_default_options, cython_compile from Cython.Compiler.Main import \ CompilationOptions, \ default_options as pyrex_default_options, \ compile as cython_compile from Cython.Compiler import Errors Errors.LEVEL = 0 # show all warnings from Cython.Compiler import Options Options.generate_cleanup_code = 3 # complete cleanup code from Cython.Compiler import DebugFlags DebugFlags.debug_temp_code_comments = 1 # RUN ALL TESTS! UNITTEST_MODULE = "Cython" UNITTEST_ROOT = os.path.join(os.getcwd(), UNITTEST_MODULE) if WITH_CYTHON: if os.path.exists(WORKDIR): for path in os.listdir(WORKDIR): if path in ("support", "Cy3"): continue shutil.rmtree(os.path.join(WORKDIR, path), ignore_errors=True) if not os.path.exists(WORKDIR): os.makedirs(WORKDIR) sys.stderr.write("Python %s\n" % sys.version) sys.stderr.write("\n") if WITH_CYTHON: from Cython.Compiler.Version import version sys.stderr.write("Running tests against Cython %s\n" % version) else: sys.stderr.write("Running tests without Cython.\n") if options.with_refnanny: from pyximport.pyxbuild import pyx_to_dll libpath = pyx_to_dll(os.path.join("Cython", "Runtime", "refnanny.pyx"), build_in_temp=True, pyxbuild_dir=os.path.join(WORKDIR, "support")) sys.path.insert(0, os.path.split(libpath)[0]) CFLAGS.append("-DCYTHON_REFNANNY=1") if options.xml_output_dir and options.fork: # doesn't currently work together sys.stderr.write("Disabling forked testing to support XML test output\n") options.fork = False if WITH_CYTHON and options.language_level == 3: sys.stderr.write("Using Cython language level 3.\n") sys.stderr.write("\n") test_bugs = False if options.tickets: for ticket_number in options.tickets: test_bugs = True cmd_args.append('.*T%s$' % ticket_number) if not test_bugs: for selector in cmd_args: if selector.startswith('bugs'): test_bugs = True import re selectors = [ re.compile(r, re.I|re.U).search for r in cmd_args ] if not selectors: selectors = [ lambda x:True ] # Chech which external modules are not present and exclude tests # which depends on them (by prefix) missing_dep_excluder = MissingDependencyExcluder(EXT_DEP_MODULES) version_dep_excluder = VersionDependencyExcluder(VER_DEP_MODULES) exclude_selectors = [missing_dep_excluder, version_dep_excluder] # want to pring msg at exit if options.exclude: exclude_selectors += [ re.compile(r, re.I|re.U).search for r in options.exclude ] if not test_bugs: exclude_selectors += [ FileListExcluder("tests/bugs.txt") ] if sys.platform in ['win32', 'cygwin'] and sys.version_info < (2,6): exclude_selectors += [ lambda x: x == "run.specialfloat" ] languages = [] if options.use_c: languages.append('c') if options.use_cpp: languages.append('cpp') test_suite = unittest.TestSuite() if options.unittests: collect_unittests(UNITTEST_ROOT, UNITTEST_MODULE + ".", test_suite, selectors) if options.doctests: collect_doctests(UNITTEST_ROOT, UNITTEST_MODULE + ".", test_suite, selectors) if options.filetests and languages: filetests = TestBuilder(ROOTDIR, WORKDIR, selectors, exclude_selectors, options.annotate_source, options.cleanup_workdir, options.cleanup_sharedlibs, options.pyregr, options.cython_only, languages, test_bugs, options.fork, options.language_level) test_suite.addTest(filetests.build_suite()) if options.system_pyregr and languages: filetests = TestBuilder(ROOTDIR, WORKDIR, selectors, exclude_selectors, options.annotate_source, options.cleanup_workdir, options.cleanup_sharedlibs, True, options.cython_only, languages, test_bugs, options.fork, options.language_level) test_suite.addTest( filetests.handle_directory( os.path.join(sys.prefix, 'lib', 'python'+sys.version[:3], 'test'), 'pyregr')) if options.xml_output_dir: from Cython.Tests.xmlrunner import XMLTestRunner test_runner = XMLTestRunner(output=options.xml_output_dir, verbose=options.verbosity > 0) else: test_runner = unittest.TextTestRunner(verbosity=options.verbosity) result = test_runner.run(test_suite) if options.coverage or options.coverage_xml: coverage.stop() ignored_modules = ('Options', 'Version', 'DebugFlags', 'CmdLine') modules = [ module for name, module in sys.modules.items() if module is not None and name.startswith('Cython.Compiler.') and name[len('Cython.Compiler.'):] not in ignored_modules ] if options.coverage: coverage.report(modules, show_missing=0) if options.coverage_xml: coverage.xml_report(modules, outfile="coverage-report.xml") if missing_dep_excluder.tests_missing_deps: sys.stderr.write("Following tests excluded because of missing dependencies on your system:\n") for test in missing_dep_excluder.tests_missing_deps: sys.stderr.write(" %s\n" % test) if options.with_refnanny: import refnanny sys.stderr.write("\n".join([repr(x) for x in refnanny.reflog])) print("ALL DONE") if options.exit_ok: return_code = 0 else: return_code = not result.wasSuccessful() try: check_thread_termination(ignore_seen=False) sys.exit(return_code) except PendingThreadsError: # normal program exit won't kill the threads, do it the hard way here os._exit(return_code)
cy3_dir = os.path.join(WORKDIR, 'Cy3') if sys.version_info >= (3,1): refactor_for_py3(DISTDIR, cy3_dir) elif os.path.isdir(cy3_dir): sys.path.insert(0, cy3_dir) else: options.with_cython = False WITH_CYTHON = options.with_cython if options.coverage or options.coverage_xml: if not WITH_CYTHON: options.coverage = options.coverage_xml = False else: from coverage import coverage as _coverage coverage = _coverage(branch=True) coverage.erase() coverage.start() if WITH_CYTHON: from Cython.Compiler.Main import \ CompilationOptions, \ default_options as pyrex_default_options, \ compile as cython_compile from Cython.Compiler import Errors Errors.LEVEL = 0 # show all warnings from Cython.Compiler import Options Options.generate_cleanup_code = 3 # complete cleanup code from Cython.Compiler import DebugFlags DebugFlags.debug_temp_code_comments = 1