test_paver_bok_choy_cmds.py 8.42 KB
Newer Older
1 2 3 4
"""
Tests for the bok-choy paver commands themselves.
Run just this test with: paver test_lib -t pavelib/paver_tests/test_paver_bok_choy_cmds.py
"""
5 6
import os
import unittest
7 8

from mock import patch, call
9
from test.test_support import EnvironmentVarGuard
10
from paver.easy import BuildFailure
11
from pavelib.utils.test.suites import BokChoyTestSuite, Pa11yCrawler
12 13 14 15

REPO_DIR = os.getcwd()


16
class TestPaverBokChoyCmd(unittest.TestCase):
17 18 19
    """
    Paver Bok Choy Command test cases
    """
20

21
    def _expected_command(self, name, store=None, verify_xss=True):
22 23 24 25
        """
        Returns the command that is expected to be run for the given test spec
        and store.
        """
26

27 28
        expected_statement = (
            "DEFAULT_STORE={default_store} "
29 30
            "SCREENSHOT_DIR='{repo_dir}/test_root/log{shard_str}' "
            "BOK_CHOY_HAR_DIR='{repo_dir}/test_root/log{shard_str}/hars' "
31
            "BOKCHOY_A11Y_CUSTOM_RULES_FILE='{repo_dir}/{a11y_custom_file}' "
32
            "SELENIUM_DRIVER_LOG_DIR='{repo_dir}/test_root/log{shard_str}' "
33
            "VERIFY_XSS='{verify_xss}' "
34
            "nosetests {repo_dir}/common/test/acceptance/{exp_text} "
35
            "--with-xunit "
36 37
            "--xunit-file={repo_dir}/reports/bok_choy{shard_str}/xunit.xml "
            "--verbosity=2 "
38
        ).format(
39
            default_store=store,
40
            repo_dir=REPO_DIR,
41
            shard_str='/shard_' + self.shard if self.shard else '',
42
            exp_text=name,
43
            a11y_custom_file='node_modules/edx-custom-a11y-rules/lib/custom_a11y_rules.js',
44
            verify_xss=verify_xss
45
        )
46
        return expected_statement
47

48 49 50
    def setUp(self):
        super(TestPaverBokChoyCmd, self).setUp()
        self.shard = os.environ.get('SHARD')
51
        self.env_var_override = EnvironmentVarGuard()
52

53 54 55 56
    def test_default(self):
        suite = BokChoyTestSuite('')
        name = 'tests'
        self.assertEqual(suite.cmd, self._expected_command(name=name))
57

58 59 60 61 62
    def test_suite_spec(self):
        spec = 'test_foo.py'
        suite = BokChoyTestSuite('', test_spec=spec)
        name = 'tests/{}'.format(spec)
        self.assertEqual(suite.cmd, self._expected_command(name=name))
63

64 65 66 67 68
    def test_class_spec(self):
        spec = 'test_foo.py:FooTest'
        suite = BokChoyTestSuite('', test_spec=spec)
        name = 'tests/{}'.format(spec)
        self.assertEqual(suite.cmd, self._expected_command(name=name))
69

70 71 72 73 74
    def test_testcase_spec(self):
        spec = 'test_foo.py:FooTest.test_bar'
        suite = BokChoyTestSuite('', test_spec=spec)
        name = 'tests/{}'.format(spec)
        self.assertEqual(suite.cmd, self._expected_command(name=name))
75

76 77 78 79 80 81 82 83
    def test_spec_with_draft_default_store(self):
        spec = 'test_foo.py'
        suite = BokChoyTestSuite('', test_spec=spec, default_store='draft')
        name = 'tests/{}'.format(spec)
        self.assertEqual(
            suite.cmd,
            self._expected_command(name=name, store='draft')
        )
84

85
    def test_invalid_default_store(self):
86
        # the cmd will dumbly compose whatever we pass in for the default_store
87 88 89 90 91 92
        suite = BokChoyTestSuite('', default_store='invalid')
        name = 'tests'
        self.assertEqual(
            suite.cmd,
            self._expected_command(name=name, store='invalid')
        )
93 94

    def test_serversonly(self):
95 96 97
        suite = BokChoyTestSuite('', serversonly=True)
        self.assertEqual(suite.cmd, "")

98 99 100 101 102 103
    def test_verify_xss(self):
        suite = BokChoyTestSuite('', verify_xss=True)
        name = 'tests'
        self.assertEqual(suite.cmd, self._expected_command(name=name, verify_xss=True))

    def test_verify_xss_env_var(self):
104
        self.env_var_override.set('VERIFY_XSS', 'False')
105 106 107
        with self.env_var_override:
            suite = BokChoyTestSuite('')
            name = 'tests'
108
            self.assertEqual(suite.cmd, self._expected_command(name=name, verify_xss=False))
109

110 111 112 113 114 115 116
    def test_test_dir(self):
        test_dir = 'foo'
        suite = BokChoyTestSuite('', test_dir=test_dir)
        self.assertEqual(
            suite.cmd,
            self._expected_command(name=test_dir)
        )
117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171

    def test_verbosity_settings_1_process(self):
        """
        Using 1 process means paver should ask for the traditional xunit plugin for plugin results
        """
        expected_verbosity_string = (
            "--with-xunit --xunit-file={repo_dir}/reports/bok_choy{shard_str}/xunit.xml --verbosity=2".format(
                repo_dir=REPO_DIR,
                shard_str='/shard_' + self.shard if self.shard else ''
            )
        )
        suite = BokChoyTestSuite('', num_processes=1)
        self.assertEqual(BokChoyTestSuite.verbosity_processes_string(suite), expected_verbosity_string)

    def test_verbosity_settings_2_processes(self):
        """
        Using multiple processes means specific xunit, coloring, and process-related settings should
        be used.
        """
        process_count = 2
        expected_verbosity_string = (
            "--with-xunitmp --xunitmp-file={repo_dir}/reports/bok_choy{shard_str}/xunit.xml"
            " --processes={procs} --no-color --process-timeout=1200".format(
                repo_dir=REPO_DIR,
                shard_str='/shard_' + self.shard if self.shard else '',
                procs=process_count
            )
        )
        suite = BokChoyTestSuite('', num_processes=process_count)
        self.assertEqual(BokChoyTestSuite.verbosity_processes_string(suite), expected_verbosity_string)

    def test_verbosity_settings_3_processes(self):
        """
        With the above test, validate that num_processes can be set to various values
        """
        process_count = 3
        expected_verbosity_string = (
            "--with-xunitmp --xunitmp-file={repo_dir}/reports/bok_choy{shard_str}/xunit.xml"
            " --processes={procs} --no-color --process-timeout=1200".format(
                repo_dir=REPO_DIR,
                shard_str='/shard_' + self.shard if self.shard else '',
                procs=process_count
            )
        )
        suite = BokChoyTestSuite('', num_processes=process_count)
        self.assertEqual(BokChoyTestSuite.verbosity_processes_string(suite), expected_verbosity_string)

    def test_invalid_verbosity_and_processes(self):
        """
        If an invalid combination of verbosity and number of processors is passed in, a
        BuildFailure should be raised
        """
        suite = BokChoyTestSuite('', num_processes=2, verbosity=3)
        with self.assertRaises(BuildFailure):
            BokChoyTestSuite.verbosity_processes_string(suite)
172 173


174
class TestPaverPa11yCrawlerCmd(unittest.TestCase):
175 176 177 178 179 180 181

    """
    Paver pa11ycrawler command test cases.  Most of the functionality is
    inherited from BokChoyTestSuite, so those tests aren't duplicated.
    """

    def setUp(self):
182
        super(TestPaverPa11yCrawlerCmd, self).setUp()
183 184 185 186 187 188 189 190

        # Mock shell commands
        mock_sh = patch('pavelib.utils.test.suites.bokchoy_suite.sh')
        self._mock_sh = mock_sh.start()

        # Cleanup mocks
        self.addCleanup(mock_sh.stop)

191
    def _expected_command(self, report_dir, start_urls):
192 193 194 195
        """
        Returns the expected command to run pa11ycrawler.
        """
        expected_statement = (
196
            'pa11ycrawler run {start_urls} '
197 198 199 200 201 202
            '--pa11ycrawler-allowed-domains=localhost '
            '--pa11ycrawler-reports-dir={report_dir} '
            '--pa11ycrawler-deny-url-matcher=logout '
            '--pa11y-reporter="1.0-json" '
            '--depth-limit=6 '
        ).format(
203
            start_urls=' '.join(start_urls),
204 205 206 207 208
            report_dir=report_dir,
        )
        return expected_statement

    def test_default(self):
209
        suite = Pa11yCrawler('')
210
        self.assertEqual(
211 212 213
            suite.cmd,
            self._expected_command(suite.pa11y_report_dir, suite.start_urls)
        )
214 215

    def test_get_test_course(self):
216
        suite = Pa11yCrawler('')
217 218 219 220 221 222 223 224 225
        suite.get_test_course()
        self._mock_sh.assert_has_calls([
            call(
                'wget {targz} -O {dir}demo_course.tar.gz'.format(targz=suite.tar_gz_file, dir=suite.imports_dir)),
            call(
                'tar zxf {dir}demo_course.tar.gz -C {dir}'.format(dir=suite.imports_dir)),
        ])

    def test_generate_html_reports(self):
226
        suite = Pa11yCrawler('')
227 228 229 230 231
        suite.generate_html_reports()
        self._mock_sh.assert_has_calls([
            call(
                'pa11ycrawler json-to-html --pa11ycrawler-reports-dir={}'.format(suite.pa11y_report_dir)),
        ])