# This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. import mozunit import pytest from unittest.mock import Mock, patch, sentinel import marionette_harness.marionette_test as marionette_test from marionette_harness.runtests import MarionetteTestRunner, MarionetteHarness, cli @pytest.fixture def harness_class(request): """ Mock based on MarionetteHarness whose run method just returns a number of failures according to the supplied test parameter """ if "num_fails_crashed" in request.fixturenames: num_fails_crashed = request.getfixturevalue("num_fails_crashed") else: num_fails_crashed = (0, 0) harness_cls = Mock(spec=MarionetteHarness) harness = harness_cls.return_value if num_fails_crashed is None: harness.run.side_effect = Exception else: harness.run.return_value = sum(num_fails_crashed) return harness_cls @pytest.fixture def runner_class(request): """ Mock based on MarionetteTestRunner, wherein the runner.failed, runner.crashed attributes are provided by a test parameter """ if "num_fails_crashed" in request.fixturenames: failures, crashed = request.getfixturevalue("num_fails_crashed") else: failures = 0 crashed = 0 mock_runner_class = Mock(spec=MarionetteTestRunner) runner = mock_runner_class.return_value runner.failed = failures runner.crashed = crashed return mock_runner_class @pytest.mark.parametrize( "num_fails_crashed,exit_code", [((0, 0), 0), ((1, 0), 10), ((0, 1), 10), (None, 1)], ) def test_cli_exit_code(num_fails_crashed, exit_code, harness_class): with pytest.raises(SystemExit) as err: cli(harness_class=harness_class) assert err.value.code == exit_code @pytest.mark.parametrize("num_fails_crashed", [(0, 0), (1, 0), (1, 1)]) def test_call_harness_with_parsed_args_yields_num_failures( mach_parsed_kwargs, runner_class, num_fails_crashed ): with patch( "marionette_harness.runtests.MarionetteHarness.parse_args" ) as parse_args: failed_or_crashed = MarionetteHarness( runner_class, args=mach_parsed_kwargs ).run() parse_args.assert_not_called() assert failed_or_crashed == sum(num_fails_crashed) def test_call_harness_with_no_args_yields_num_failures(runner_class): with patch( "marionette_harness.runtests.MarionetteHarness.parse_args", return_value={"tests": []}, ) as parse_args: failed_or_crashed = MarionetteHarness(runner_class).run() assert parse_args.call_count == 1 assert failed_or_crashed == 0 def test_args_passed_to_runner_class(mach_parsed_kwargs, runner_class): arg_list = list(mach_parsed_kwargs.keys()) arg_list.remove("tests") mach_parsed_kwargs.update([(a, getattr(sentinel, a)) for a in arg_list]) harness = MarionetteHarness(runner_class, args=mach_parsed_kwargs) harness.process_args = Mock() harness.run() for arg in arg_list: assert harness._runner_class.call_args[1][arg] is getattr(sentinel, arg) def test_harness_sets_up_default_test_handlers(mach_parsed_kwargs): """ If the necessary TestCase is not in test_handlers, tests are omitted silently """ harness = MarionetteHarness(args=mach_parsed_kwargs) mach_parsed_kwargs.pop("tests") runner = harness._runner_class(**mach_parsed_kwargs) assert marionette_test.MarionetteTestCase in runner.test_handlers if __name__ == "__main__": mozunit.main("-p", "no:terminalreporter", "--log-tbpl=-", "--capture", "no")