test_marionette_harness.py (3732B)
1 # This Source Code Form is subject to the terms of the Mozilla Public 2 # License, v. 2.0. If a copy of the MPL was not distributed with this 3 # file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 5 6 import mozunit 7 import pytest 8 9 from unittest.mock import Mock, patch, sentinel 10 11 import marionette_harness.marionette_test as marionette_test 12 13 from marionette_harness.runtests import MarionetteTestRunner, MarionetteHarness, cli 14 15 16 @pytest.fixture 17 def harness_class(request): 18 """ 19 Mock based on MarionetteHarness whose run method just returns a number of 20 failures according to the supplied test parameter 21 """ 22 if "num_fails_crashed" in request.fixturenames: 23 num_fails_crashed = request.getfixturevalue("num_fails_crashed") 24 else: 25 num_fails_crashed = (0, 0) 26 harness_cls = Mock(spec=MarionetteHarness) 27 harness = harness_cls.return_value 28 if num_fails_crashed is None: 29 harness.run.side_effect = Exception 30 else: 31 harness.run.return_value = sum(num_fails_crashed) 32 return harness_cls 33 34 35 @pytest.fixture 36 def runner_class(request): 37 """ 38 Mock based on MarionetteTestRunner, wherein the runner.failed, 39 runner.crashed attributes are provided by a test parameter 40 """ 41 if "num_fails_crashed" in request.fixturenames: 42 failures, crashed = request.getfixturevalue("num_fails_crashed") 43 else: 44 failures = 0 45 crashed = 0 46 mock_runner_class = Mock(spec=MarionetteTestRunner) 47 runner = mock_runner_class.return_value 48 runner.failed = failures 49 runner.crashed = crashed 50 return mock_runner_class 51 52 53 @pytest.mark.parametrize( 54 "num_fails_crashed,exit_code", 55 [((0, 0), 0), ((1, 0), 10), ((0, 1), 10), (None, 1)], 56 ) 57 def test_cli_exit_code(num_fails_crashed, exit_code, harness_class): 58 with pytest.raises(SystemExit) as err: 59 cli(harness_class=harness_class) 60 assert err.value.code == exit_code 61 62 63 @pytest.mark.parametrize("num_fails_crashed", [(0, 0), (1, 0), (1, 1)]) 64 def test_call_harness_with_parsed_args_yields_num_failures( 65 mach_parsed_kwargs, runner_class, num_fails_crashed 66 ): 67 with patch( 68 "marionette_harness.runtests.MarionetteHarness.parse_args" 69 ) as parse_args: 70 failed_or_crashed = MarionetteHarness( 71 runner_class, args=mach_parsed_kwargs 72 ).run() 73 parse_args.assert_not_called() 74 assert failed_or_crashed == sum(num_fails_crashed) 75 76 77 def test_call_harness_with_no_args_yields_num_failures(runner_class): 78 with patch( 79 "marionette_harness.runtests.MarionetteHarness.parse_args", 80 return_value={"tests": []}, 81 ) as parse_args: 82 failed_or_crashed = MarionetteHarness(runner_class).run() 83 assert parse_args.call_count == 1 84 assert failed_or_crashed == 0 85 86 87 def test_args_passed_to_runner_class(mach_parsed_kwargs, runner_class): 88 arg_list = list(mach_parsed_kwargs.keys()) 89 arg_list.remove("tests") 90 mach_parsed_kwargs.update([(a, getattr(sentinel, a)) for a in arg_list]) 91 harness = MarionetteHarness(runner_class, args=mach_parsed_kwargs) 92 harness.process_args = Mock() 93 harness.run() 94 for arg in arg_list: 95 assert harness._runner_class.call_args[1][arg] is getattr(sentinel, arg) 96 97 98 def test_harness_sets_up_default_test_handlers(mach_parsed_kwargs): 99 """ 100 If the necessary TestCase is not in test_handlers, 101 tests are omitted silently 102 """ 103 harness = MarionetteHarness(args=mach_parsed_kwargs) 104 mach_parsed_kwargs.pop("tests") 105 runner = harness._runner_class(**mach_parsed_kwargs) 106 assert marionette_test.MarionetteTestCase in runner.test_handlers 107 108 109 if __name__ == "__main__": 110 mozunit.main("-p", "no:terminalreporter", "--log-tbpl=-", "--capture", "no")