bok_choy.py 6.81 KB
Newer Older
1 2 3 4 5 6 7
"""
Run acceptance tests that use the bok-choy framework
http://bok-choy.readthedocs.org/en/latest/
"""
from paver.easy import task, needs, cmdopts, sh
from pavelib.utils.test.suites.bokchoy_suite import BokChoyTestSuite
from pavelib.utils.envs import Env
Minh Tue Vo committed
8
from pavelib.utils.test.utils import check_firefox_version
9
from optparse import make_option
10
import os
11 12 13 14

try:
    from pygments.console import colorize
except ImportError:
15
    colorize = lambda color, text: text
16 17 18

__test__ = False  # do not collect

19
BOKCHOY_OPTS = [
20 21
    ('test_spec=', 't', 'Specific test to run'),
    ('fasttest', 'a', 'Skip some setup'),
22 23
    ('serversonly', 'r', 'Prepare suite and leave servers running'),
    ('testsonly', 'o', 'Assume servers are running and execute tests only'),
24
    ('extra_args=', 'e', 'adds as extra args to the test command'),
25
    ('default_store=', 's', 'Default modulestore'),
26
    ('test_dir=', 'd', 'Directory for finding tests (relative to common/test/acceptance)'),
27
    ('num_processes=', 'n', 'Number of test threads (for multiprocessing)'),
28 29 30
    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"),
31
    make_option("--pdb", action="store_true", help="Drop into debugger on failures or errors"),
Minh Tue Vo committed
32
    make_option("--skip_firefox_version_validation", action='store_false', dest="validate_firefox_version")
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
]


def parse_bokchoy_opts(options):
    """
    Parses bok choy options.

    Returns: dict of options.
    """
    return {
        'test_spec': getattr(options, 'test_spec', None),
        'fasttest': getattr(options, 'fasttest', False),
        'num_processes': int(getattr(options, 'num_processes', 1)),
        'serversonly': getattr(options, 'serversonly', False),
        'testsonly': getattr(options, 'testsonly', False),
        'default_store': getattr(options, 'default_store', os.environ.get('DEFAULT_STORE', 'split')),
        'verbosity': getattr(options, 'verbosity', 2),
        'extra_args': getattr(options, 'extra_args', ''),
        'pdb': getattr(options, 'pdb', False),
        'test_dir': getattr(options, 'test_dir', 'tests'),
    }


@task
@needs('pavelib.prereqs.install_prereqs')
@cmdopts(BOKCHOY_OPTS)
59 60 61
def test_bokchoy(options):
    """
    Run acceptance tests that use the bok-choy framework.
62 63 64 65
    Skips some static asset steps if `fasttest` is True.
    Using 'serversonly' will prepare and run servers, leaving a process running in the terminal. At
        the same time, a user can open a separate terminal and use 'testsonly' for executing tests against
        those running servers.
66 67 68 69 70 71 72 73

    `test_spec` is a nose-style test specifier relative to the test directory
    Examples:
    - path/to/test.py
    - path/to/test.py:TestFoo
    - path/to/test.py:TestFoo.test_bar
    It can also be left blank to run all tests in the suite.
    """
74 75 76 77 78 79
    # Note: Bok Choy uses firefox if SELENIUM_BROWSER is not set. So we are using
    # firefox as the default here.
    using_firefox = (os.environ.get('SELENIUM_BROWSER', 'firefox') == 'firefox')
    validate_firefox = getattr(options, 'validate_firefox_version', using_firefox)

    if validate_firefox:
Minh Tue Vo committed
80
        check_firefox_version()
81

82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
    opts = parse_bokchoy_opts(options)
    run_bokchoy(**opts)


@task
@needs('pavelib.prereqs.install_prereqs')
@cmdopts(BOKCHOY_OPTS)
def test_a11y(options):
    """
    Run accessibility tests that use the bok-choy framework.
    Skips some static asset steps if `fasttest` is True.
    Using 'serversonly' will prepare and run servers, leaving a process running in the terminal. At
        the same time, a user can open a separate terminal and use 'testsonly' for executing tests against
        those running servers.

    `test_spec` is a nose-style test specifier relative to the test directory
    Examples:
    - path/to/test.py
    - path/to/test.py:TestFoo
    - path/to/test.py:TestFoo.test_bar
    It can also be left blank to run all tests in the suite that are tagged
    with `@attr("a11y")`.
    """
    opts = parse_bokchoy_opts(options)
    opts['report_dir'] = Env.BOK_CHOY_A11Y_REPORT_DIR
    opts['coveragerc'] = Env.BOK_CHOY_A11Y_COVERAGERC
    opts['extra_args'] = opts['extra_args'] + ' -a "a11y" '
109
    run_bokchoy(**opts)
110 111 112 113 114 115 116 117


@task
@needs('pavelib.prereqs.install_prereqs')
@cmdopts([
    ('test_spec=', 't', 'Specific test to run'),
    ('fasttest', 'a', 'Skip some setup'),
    ('imports_dir=', 'd', 'Directory containing (un-archived) courses to be imported'),
118
    ('default_store=', 's', 'Default modulestore'),
119 120 121 122 123 124 125 126 127 128 129
    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"),
])
def perf_report_bokchoy(options):
    """
    Generates a har file for with page performance info.
    """
    opts = {
        'test_spec': getattr(options, 'test_spec', None),
        'fasttest': getattr(options, 'fasttest', False),
130
        'default_store': getattr(options, 'default_store', os.environ.get('DEFAULT_STORE', 'split')),
131 132 133
        'imports_dir': getattr(options, 'imports_dir', None),
        'verbosity': getattr(options, 'verbosity', 2),
        'test_dir': 'performance',
134
    }
135 136 137 138 139 140 141
    run_bokchoy(**opts)


def run_bokchoy(**opts):
    """
    Runs BokChoyTestSuite with the given options.
    """
142 143 144 145
    test_suite = BokChoyTestSuite('bok-choy', **opts)
    msg = colorize(
        'green',
        'Running tests using {default_store} modulestore.'.format(
146
            default_store=test_suite.default_store,
147
        )
148
    )
149
    print msg
150
    test_suite.run()
151 152


153
def parse_coverage(report_dir, coveragerc):
154
    """
155
    Generate coverage reports for bok-choy or a11y tests
156
    """
157
    report_dir.makedirs_p()
158 159

    msg = colorize('green', "Combining coverage reports")
160
    print msg
161 162 163 164

    sh("coverage combine --rcfile={}".format(coveragerc))

    msg = colorize('green', "Generating coverage reports")
165
    print msg
166 167 168 169

    sh("coverage html --rcfile={}".format(coveragerc))
    sh("coverage xml --rcfile={}".format(coveragerc))
    sh("coverage report --rcfile={}".format(coveragerc))
170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195


@task
def bokchoy_coverage():
    """
    Generate coverage reports for bok-choy tests
    """
    parse_coverage(
        Env.BOK_CHOY_REPORT_DIR,
        Env.BOK_CHOY_COVERAGERC
    )


@task
def a11y_coverage():
    """
    Generate coverage reports for a11y tests. Note that this coverage report
    is just a guideline to find areas that are missing tests.  If the view
    isn't 'covered', there definitely isn't a test for it.  If it is
    'covered', we are loading that page during the tests but not necessarily
    calling ``page.a11y_audit.check_for_accessibility_errors`` on it.
    """
    parse_coverage(
        Env.BOK_CHOY_A11Y_REPORT_DIR,
        Env.BOK_CHOY_A11Y_COVERAGERC
    )