Files
edx-platform/pavelib/tests.py
2015-05-06 11:31:50 -04:00

276 lines
9.5 KiB
Python

"""
Unit test tasks
"""
import os
import sys
from paver.easy import sh, task, cmdopts, needs, call_task, no_help
from pavelib.utils.test import suites
from pavelib.utils.envs import Env
from optparse import make_option
try:
from pygments.console import colorize
except ImportError:
colorize = lambda color, text: text # pylint: disable-msg=invalid-name
__test__ = False # do not collect
@task
@needs(
'pavelib.prereqs.install_prereqs',
'pavelib.utils.test.utils.clean_reports_dir',
)
@cmdopts([
("system=", "s", "System to act on"),
("test_id=", "t", "Test id"),
("failed", "f", "Run only failed tests"),
("fail_fast", "x", "Run only failed tests"),
("fasttest", "a", "Run without collectstatic"),
('extra_args=', 'e', 'adds as extra args to the test command'),
('cov_args=', 'c', 'adds as args to coverage for the test run'),
('skip_clean', 'C', 'skip cleaning repository before running tests'),
make_option("--verbose", action="store_const", const=2, dest="verbosity"),
make_option("-q", "--quiet", action="store_const", const=0, dest="verbosity"),
make_option("-v", "--verbosity", action="count", dest="verbosity", default=1),
make_option("--pdb", action="store_true", help="Drop into debugger on failures or errors"),
], share_with=['pavelib.utils.test.utils.clean_reports_dir'])
def test_system(options):
"""
Run tests on our djangoapps for lms and cms
"""
system = getattr(options, 'system', None)
test_id = getattr(options, 'test_id', None)
opts = {
'failed_only': getattr(options, 'failed', None),
'fail_fast': getattr(options, 'fail_fast', None),
'fasttest': getattr(options, 'fasttest', None),
'verbosity': getattr(options, 'verbosity', 1),
'extra_args': getattr(options, 'extra_args', ''),
'cov_args': getattr(options, 'cov_args', ''),
'skip_clean': getattr(options, 'skip_clean', False),
'pdb': getattr(options, 'pdb', False),
}
if test_id:
if not system:
system = test_id.split('/')[0]
if system in ['common', 'openedx']:
system = 'lms'
opts['test_id'] = test_id
if test_id or system:
system_tests = [suites.SystemTestSuite(system, **opts)]
else:
system_tests = []
for syst in ('cms', 'lms'):
system_tests.append(suites.SystemTestSuite(syst, **opts))
test_suite = suites.PythonTestSuite('python tests', subsuites=system_tests, **opts)
test_suite.run()
@task
@needs(
'pavelib.prereqs.install_prereqs',
'pavelib.utils.test.utils.clean_reports_dir',
)
@cmdopts([
("lib=", "l", "lib to test"),
("test_id=", "t", "Test id"),
("failed", "f", "Run only failed tests"),
("fail_fast", "x", "Run only failed tests"),
('extra_args=', 'e', 'adds as extra args to the test command'),
('cov_args=', 'c', 'adds as args to coverage for the test run'),
('skip_clean', 'C', 'skip cleaning repository before running tests'),
make_option("--verbose", action="store_const", const=2, dest="verbosity"),
make_option("-q", "--quiet", action="store_const", const=0, dest="verbosity"),
make_option("-v", "--verbosity", action="count", dest="verbosity", default=1),
make_option("--pdb", action="store_true", help="Drop into debugger on failures or errors"),
], share_with=['pavelib.utils.test.utils.clean_reports_dir'])
def test_lib(options):
"""
Run tests for common/lib/ and pavelib/ (paver-tests)
"""
lib = getattr(options, 'lib', None)
test_id = getattr(options, 'test_id', lib)
opts = {
'failed_only': getattr(options, 'failed', None),
'fail_fast': getattr(options, 'fail_fast', None),
'verbosity': getattr(options, 'verbosity', 1),
'extra_args': getattr(options, 'extra_args', ''),
'cov_args': getattr(options, 'cov_args', ''),
'skip_clean': getattr(options, 'skip_clean', False),
'pdb': getattr(options, 'pdb', False),
}
if test_id:
if '/' in test_id:
lib = '/'.join(test_id.split('/')[0:3])
else:
lib = 'common/lib/' + test_id.split('.')[0]
opts['test_id'] = test_id
lib_tests = [suites.LibTestSuite(lib, **opts)]
else:
lib_tests = [suites.LibTestSuite(d, **opts) for d in Env.LIB_TEST_DIRS]
test_suite = suites.PythonTestSuite('python tests', subsuites=lib_tests, **opts)
test_suite.run()
@task
@needs(
'pavelib.prereqs.install_prereqs',
'pavelib.utils.test.utils.clean_reports_dir',
)
@cmdopts([
("failed", "f", "Run only failed tests"),
("fail_fast", "x", "Run only failed tests"),
('extra_args=', 'e', 'adds as extra args to the test command'),
('cov_args=', 'c', 'adds as args to coverage for the test run'),
make_option("--verbose", action="store_const", const=2, dest="verbosity"),
make_option("-q", "--quiet", action="store_const", const=0, dest="verbosity"),
make_option("-v", "--verbosity", action="count", dest="verbosity", default=1),
make_option("--pdb", action="store_true", help="Drop into debugger on failures or errors"),
])
def test_python(options):
"""
Run all python tests
"""
opts = {
'failed_only': getattr(options, 'failed', None),
'fail_fast': getattr(options, 'fail_fast', None),
'verbosity': getattr(options, 'verbosity', 1),
'extra_args': getattr(options, 'extra_args', ''),
'cov_args': getattr(options, 'cov_args', ''),
'pdb': getattr(options, 'pdb', False),
}
python_suite = suites.PythonTestSuite('Python Tests', **opts)
python_suite.run()
@task
@needs(
'pavelib.prereqs.install_prereqs',
'pavelib.utils.test.utils.clean_reports_dir',
)
@cmdopts([
("suites", "s", "List of unit test suites to run. (js, lib, cms, lms)"),
('extra_args=', 'e', 'adds as extra args to the test command'),
('cov_args=', 'c', 'adds as args to coverage for the test run'),
make_option("--verbose", action="store_const", const=2, dest="verbosity"),
make_option("-q", "--quiet", action="store_const", const=0, dest="verbosity"),
make_option("-v", "--verbosity", action="count", dest="verbosity", default=1),
make_option("--pdb", action="store_true", help="Drop into debugger on failures or errors"),
])
def test(options):
"""
Run all tests
"""
opts = {
'verbosity': getattr(options, 'verbosity', 1),
'extra_args': getattr(options, 'extra_args', ''),
'cov_args': getattr(options, 'cov_args', ''),
'pdb': getattr(options, 'pdb', False),
}
# Subsuites to be added to the main suite
python_suite = suites.PythonTestSuite('Python Tests', **opts)
js_suite = suites.JsTestSuite('JS Tests', mode='run', with_coverage=True)
# Main suite to be run
all_unittests_suite = suites.TestSuite('All Tests', subsuites=[js_suite, python_suite])
all_unittests_suite.run()
@task
@needs('pavelib.prereqs.install_prereqs')
@cmdopts([
("compare_branch=", "b", "Branch to compare against, defaults to origin/master"),
])
def coverage(options):
"""
Build the html, xml, and diff coverage reports
"""
compare_branch = getattr(options, 'compare_branch', 'origin/master')
for directory in Env.LIB_TEST_DIRS + ['cms', 'lms']:
report_dir = Env.REPORT_DIR / directory
if (report_dir / '.coverage').isfile():
# Generate the coverage.py HTML report
sh("coverage html --rcfile={dir}/.coveragerc".format(dir=directory))
# Generate the coverage.py XML report
sh("coverage xml -o {report_dir}/coverage.xml --rcfile={dir}/.coveragerc".format(
report_dir=report_dir,
dir=directory
))
call_task('diff_coverage', options=dict(options))
@no_help
@task
@needs('pavelib.prereqs.install_prereqs')
def combine_jenkins_coverage():
"""
Combine coverage reports from jenkins build flow.
"""
coveragerc = Env.REPO_ROOT / 'test_root' / '.jenkins-coveragerc'
for directory in Env.LIB_TEST_DIRS + ['cms', 'lms']:
report_dir = Env.REPORT_DIR / directory
# Only try to combine the coverage if we've run the tests.
if report_dir.isdir():
sh(
"cd {} && coverage combine --rcfile={}".format(
report_dir,
coveragerc,
)
)
@task
@needs('pavelib.prereqs.install_prereqs')
@cmdopts([
("compare_branch=", "b", "Branch to compare against, defaults to origin/master"),
])
def diff_coverage(options):
"""
Build the diff coverage reports
"""
compare_branch = getattr(options, 'compare_branch', 'origin/master')
# Find all coverage XML files (both Python and JavaScript)
xml_reports = []
for filepath in Env.REPORT_DIR.walk():
if filepath.basename() == 'coverage.xml':
xml_reports.append(filepath)
if not xml_reports:
err_msg = colorize(
'red',
"No coverage info found. Run `paver test` before running `paver coverage`.\n"
)
sys.stderr.write(err_msg)
else:
xml_report_str = ' '.join(xml_reports)
diff_html_path = os.path.join(Env.REPORT_DIR, 'diff_coverage_combined.html')
# Generate the diff coverage reports (HTML and console)
sh(
"diff-cover {xml_report_str} --compare-branch={compare_branch} "
"--html-report {diff_html_path}".format(
xml_report_str=xml_report_str,
compare_branch=compare_branch,
diff_html_path=diff_html_path,
)
)
print("\n")