From 290ff9930a33a5c165d3952a7bd1ed858b7a4572 Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Sun, 29 Mar 2009 20:23:05 +0000 Subject: [PATCH] - coverage dumps out separate reports for individual packages - other coverage tips --- README.unittests | 3 +++ test/profiling/alltests.py | 3 +++ test/testlib/config.py | 47 ++++++++++++++++++++++++++++++-------- 3 files changed, 44 insertions(+), 9 deletions(-) diff --git a/README.unittests b/README.unittests index 4698494234..f70f6ab177 100644 --- a/README.unittests +++ b/README.unittests @@ -131,6 +131,9 @@ statements that are missed with !, by running the coverage.py utility with the This will create a new annotated file ./lib/sqlalchemy/sql.py,cover. Pretty cool! +BIG COVERAGE TIP !!! There is an issue where existing .pyc files may +store the incorrect filepaths, which will break the coverage system. If +coverage numbers are coming out as low/zero, try deleting all .pyc files. TESTING NEW DIALECTS -------------------- diff --git a/test/profiling/alltests.py b/test/profiling/alltests.py index 9f35007481..19401098c1 100644 --- a/test/profiling/alltests.py +++ b/test/profiling/alltests.py @@ -11,6 +11,9 @@ def suite(): 'profiling.zoomark_orm', ) alltests = unittest.TestSuite() + if testenv.testlib.config.coverage_enabled: + return alltests + for name in modules_to_test: mod = __import__(name) for token in name.split('.')[1:]: diff --git a/test/testlib/config.py b/test/testlib/config.py index ac9f397177..cef4c6e1dc 100644 --- a/test/testlib/config.py +++ b/test/testlib/config.py @@ -9,6 +9,7 @@ db_label, db_url, db_opts = None, None, {} options = None file_config = None +coverage_enabled = False base_config = """ [db] @@ -77,24 +78,50 @@ def _log(option, opt_str, value, parser): elif opt_str.endswith('-debug'): logging.getLogger(value).setLevel(logging.DEBUG) -def _start_coverage(option, opt_str, value, parser): +def _start_cumulative_coverage(option, opt_str, value, parser): + _start_coverage(option, opt_str, value, parser, erase=False) + +def _start_coverage(option, opt_str, value, parser, erase=True): import sys, atexit, coverage true_out = sys.stdout - - def _iter_covered_files(): - import sqlalchemy - for rec in os.walk(os.path.dirname(sqlalchemy.__file__)): + + global coverage_enabled + coverage_enabled = True + + def _iter_covered_files(mod, recursive=True): + + if recursive: + ff = os.walk + else: + ff = os.listdir + + for rec in ff(os.path.dirname(mod.__file__)): for x in rec[2]: if x.endswith('.py'): yield os.path.join(rec[0], x) + def _stop(): coverage.stop() true_out.write("\nPreparing coverage report...\n") - coverage.report(list(_iter_covered_files()), - show_missing=False, ignore_errors=False, - file=true_out) + + from sqlalchemy import sql, orm, engine, \ + ext, databases, log + + import sqlalchemy + + for modset in [ + _iter_covered_files(sqlalchemy, recursive=False), + _iter_covered_files(databases), + _iter_covered_files(engine), + _iter_covered_files(ext), + _iter_covered_files(orm), + ]: + coverage.report(list(modset), + show_missing=False, ignore_errors=False, + file=true_out) atexit.register(_stop) - coverage.erase() + if erase: + coverage.erase() coverage.start() def _list_dbs(*args): @@ -151,6 +178,8 @@ opt("--table-option", action="append", dest="tableopts", default=[], help="Add a dialect-specific table option, key=value") opt("--coverage", action="callback", callback=_start_coverage, help="Dump a full coverage report after running tests") +opt("--cumulative-coverage", action="callback", callback=_start_cumulative_coverage, + help="Like --coverage, but accumlate coverage into the current DB") opt("--profile", action="append", dest="profile_targets", default=[], help="Enable a named profile target (multiple OK.)") opt("--profile-sort", action="store", dest="profile_sort", default=None, -- 2.47.2