Bug 1445944 - [mozrunner] Convert mozrunner unittests to the pytest format
This will make it easier to add the ChromeRunner tests in the next couple of
commits.
MozReview-Commit-ID: 2Nfz92FStSX
rename from testing/mozbase/mozrunner/tests/mozrunnertest.py
rename to testing/mozbase/mozrunner/tests/conftest.py
--- a/testing/mozbase/mozrunner/tests/mozrunnertest.py
+++ b/testing/mozbase/mozrunner/tests/conftest.py
@@ -1,36 +1,71 @@
# 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/.
from __future__ import absolute_import
import os
-import unittest
+import threading
+from time import sleep
import mozprofile
import mozrunner
+import pytest
+from moztest.selftest import fixtures
+
+
+@pytest.fixture
+def profile():
+ return mozprofile.FirefoxProfile()
+
+
+@pytest.fixture
+def get_binary():
+ if 'BROWSER_PATH' in os.environ:
+ os.environ['GECKO_BINARY_PATH'] = os.environ['BROWSER_PATH']
+
+ def inner(app):
+ if app != 'firefox':
+ pytest.xfail(reason="{} support not implemented".format(app))
+
+ binary = fixtures.binary()
+ if not binary:
+ pytest.skip("could not find a {} binary".format(app))
+ return binary
+ return inner
-@unittest.skipIf(not os.environ.get('BROWSER_PATH'),
- 'No binary has been specified.')
-class MozrunnerTestCase(unittest.TestCase):
+@pytest.fixture
+def runner(profile, get_binary):
+ binary = get_binary('firefox')
+ return mozrunner.FirefoxRunner(binary, profile=profile)
+
- def setUp(self):
- self.pids = []
- self.threads = []
-
- self.profile = mozprofile.FirefoxProfile()
- self.runner = mozrunner.FirefoxRunner(os.environ['BROWSER_PATH'],
- profile=self.profile)
+class RunnerThread(threading.Thread):
+ def __init__(self, runner, start=False, timeout=1):
+ threading.Thread.__init__(self)
+ self.runner = runner
+ self.timeout = timeout
+ self.do_start = start
- def tearDown(self):
- for thread in self.threads:
- thread.join()
+ def run(self):
+ sleep(self.timeout)
+ if self.do_start:
+ self.runner.start()
+ else:
+ self.runner.stop()
- self.runner.cleanup()
- # Clean-up any left over and running processes
- for pid in self.pids:
- # TODO: Bug 925408
- # mozprocess is not able yet to kill specific processes
- pass
+@pytest.fixture
+def create_thread():
+ threads = []
+
+ def inner(*args, **kwargs):
+ thread = RunnerThread(*args, **kwargs)
+ threads.append(thread)
+ return thread
+
+ yield inner
+
+ for thread in threads:
+ thread.join()
--- a/testing/mozbase/mozrunner/tests/test_crash.py
+++ b/testing/mozbase/mozrunner/tests/test_crash.py
@@ -1,44 +1,35 @@
#!/usr/bin/env python
# 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/.
from __future__ import absolute_import
-import mock
+from mock import patch
+
import mozunit
-
-import mozrunnertest
+import pytest
-class MozrunnerCrashTestCase(mozrunnertest.MozrunnerTestCase):
-
- @mock.patch('mozcrash.log_crashes', return_value=2)
- def test_crash_count_with_logger(self, log_crashes):
- self.assertEqual(self.runner.crashed, 0)
- self.assertEqual(self.runner.check_for_crashes(), 2)
- self.assertEqual(self.runner.crashed, 2)
- self.assertEqual(self.runner.check_for_crashes(), 2)
- self.assertEqual(self.runner.crashed, 4)
-
- log_crashes.return_value = 0
- self.assertEqual(self.runner.check_for_crashes(), 0)
- self.assertEqual(self.runner.crashed, 4)
+@pytest.mark.parametrize('logger', [True, False])
+def test_crash_count_with_or_without_logger(runner, logger):
+ if not logger:
+ runner.logger = None
+ fn = 'check_for_crashes'
+ else:
+ fn = 'log_crashes'
- @mock.patch('mozcrash.check_for_crashes', return_value=2)
- def test_crash_count_without_logger(self, check_for_crashes):
- self.runner.logger = None
+ with patch('mozcrash.{}'.format(fn), return_value=2) as mock:
+ assert runner.crashed == 0
+ assert runner.check_for_crashes() == 2
+ assert runner.crashed == 2
+ assert runner.check_for_crashes() == 2
+ assert runner.crashed == 4
- self.assertEqual(self.runner.crashed, 0)
- self.assertEqual(self.runner.check_for_crashes(), 2)
- self.assertEqual(self.runner.crashed, 2)
- self.assertEqual(self.runner.check_for_crashes(), 2)
- self.assertEqual(self.runner.crashed, 4)
-
- check_for_crashes.return_value = 0
- self.assertEqual(self.runner.check_for_crashes(), 0)
- self.assertEqual(self.runner.crashed, 4)
+ mock.return_value = 0
+ assert runner.check_for_crashes() == 0
+ assert runner.crashed == 4
if __name__ == '__main__':
mozunit.main()
--- a/testing/mozbase/mozrunner/tests/test_interactive.py
+++ b/testing/mozbase/mozrunner/tests/test_interactive.py
@@ -1,61 +1,42 @@
#!/usr/bin/env python
from __future__ import absolute_import
-import threading
from time import sleep
import mozunit
-import mozrunnertest
-
-class RunnerThread(threading.Thread):
+def test_run_interactive(runner, create_thread):
+ """Bug 965183: Run process in interactive mode and call wait()"""
+ runner.start(interactive=True)
- def __init__(self, runner, timeout=10):
- threading.Thread.__init__(self)
- self.runner = runner
- self.timeout = timeout
+ thread = create_thread(runner, timeout=2)
+ thread.start()
- def run(self):
- sleep(self.timeout)
- self.runner.stop()
+ # This is a blocking call. So the process should be killed by the thread
+ runner.wait()
+ thread.join()
+ assert not runner.is_running()
-class MozrunnerInteractiveTestCase(mozrunnertest.MozrunnerTestCase):
-
- def test_run_interactive(self):
- """Bug 965183: Run process in interactive mode and call wait()"""
- pid = self.runner.start(interactive=True)
- self.pids.append(pid)
+def test_stop_interactive(runner):
+ """Bug 965183: Explicitely stop process in interactive mode"""
+ runner.start(interactive=True)
+ runner.stop()
- thread = RunnerThread(self.runner, 5)
- self.threads.append(thread)
- thread.start()
-
- # This is a blocking call. So the process should be killed by the thread
- self.runner.wait()
- thread.join()
- self.assertFalse(self.runner.is_running())
- def test_stop_interactive(self):
- """Bug 965183: Explicitely stop process in interactive mode"""
- pid = self.runner.start(interactive=True)
- self.pids.append(pid)
-
- self.runner.stop()
+def test_wait_after_process_finished(runner):
+ """Wait after the process has been stopped should not raise an error"""
+ runner.start(interactive=True)
+ sleep(1)
+ runner.process_handler.kill()
- def test_wait_after_process_finished(self):
- """Wait after the process has been stopped should not raise an error"""
- self.runner.start(interactive=True)
- sleep(5)
- self.runner.process_handler.kill()
+ returncode = runner.wait(1)
- returncode = self.runner.wait(1)
-
- self.assertNotIn(returncode, [None, 0])
- self.assertIsNotNone(self.runner.process_handler)
+ assert returncode not in [None, 0]
+ assert runner.process_handler is not None
if __name__ == '__main__':
mozunit.main()
--- a/testing/mozbase/mozrunner/tests/test_start.py
+++ b/testing/mozbase/mozrunner/tests/test_start.py
@@ -1,53 +1,52 @@
#!/usr/bin/env python
from __future__ import absolute_import
from time import sleep
import mozunit
-import mozrunnertest
+
+def test_start_process(runner):
+ """Start the process and test properties"""
+ assert runner.process_handler is None
+
+ runner.start()
+
+ assert runner.is_running()
+ assert runner.process_handler is not None
-class MozrunnerStartTestCase(mozrunnertest.MozrunnerTestCase):
-
- def test_start_process(self):
- """Start the process and test properties"""
- self.assertIsNone(self.runner.process_handler)
-
- self.runner.start()
+def test_start_process_called_twice(runner):
+ """Start the process twice and test that first process is gone"""
+ runner.start()
+ # Bug 925480
+ # Make a copy until mozprocess can kill a specific process
+ process_handler = runner.process_handler
- self.assertTrue(self.runner.is_running())
- self.assertIsNotNone(self.runner.process_handler)
+ runner.start()
- def test_start_process_called_twice(self):
- """Start the process twice and test that first process is gone"""
- self.runner.start()
- # Bug 925480
- # Make a copy until mozprocess can kill a specific process
- process_handler = self.runner.process_handler
+ try:
+ assert process_handler.wait(1) not in [None, 0]
+ finally:
+ process_handler.kill()
+
- self.runner.start()
+def test_start_with_timeout(runner):
+ """Start the process and set a timeout"""
+ runner.start(timeout=0.1)
+ sleep(1)
- try:
- self.assertNotIn(process_handler.wait(1), [None, 0])
- finally:
- process_handler.kill()
+ assert not runner.is_running()
- def test_start_with_timeout(self):
- """Start the process and set a timeout"""
- self.runner.start(timeout=2)
- sleep(5)
-
- self.assertFalse(self.runner.is_running())
- def test_start_with_outputTimeout(self):
- """Start the process and set a timeout"""
- self.runner.start(outputTimeout=2)
- sleep(15)
+def test_start_with_outputTimeout(runner):
+ """Start the process and set a timeout"""
+ runner.start(outputTimeout=0.1)
+ sleep(1)
- self.assertFalse(self.runner.is_running())
+ assert not runner.is_running()
if __name__ == '__main__':
mozunit.main()
--- a/testing/mozbase/mozrunner/tests/test_states.py
+++ b/testing/mozbase/mozrunner/tests/test_states.py
@@ -1,26 +1,25 @@
#!/usr/bin/env python
from __future__ import absolute_import
-import mozrunner
+import mozunit
+import pytest
-import mozunit
-
-import mozrunnertest
+from mozrunner import RunnerNotStartedError
-class MozrunnerStatesTestCase(mozrunnertest.MozrunnerTestCase):
+def test_errors_before_start(runner):
+ """Bug 965714: Not started errors before start() is called"""
- def test_errors_before_start(self):
- """Bug 965714: Not started errors before start() is called"""
+ with pytest.raises(RunnerNotStartedError):
+ runner.is_running()
- def test_returncode():
- return self.runner.returncode
+ with pytest.raises(RunnerNotStartedError):
+ runner.returncode
- self.assertRaises(mozrunner.RunnerNotStartedError, self.runner.is_running)
- self.assertRaises(mozrunner.RunnerNotStartedError, test_returncode)
- self.assertRaises(mozrunner.RunnerNotStartedError, self.runner.wait)
+ with pytest.raises(RunnerNotStartedError):
+ runner.wait()
if __name__ == '__main__':
mozunit.main()
--- a/testing/mozbase/mozrunner/tests/test_stop.py
+++ b/testing/mozbase/mozrunner/tests/test_stop.py
@@ -4,44 +4,40 @@
# You can obtain one at http://mozilla.org/MPL/2.0/.
from __future__ import absolute_import
import signal
import mozunit
-import mozrunnertest
+
+def test_stop_process(runner):
+ """Stop the process and test properties"""
+ runner.start()
+ returncode = runner.stop()
+
+ assert not runner.is_running()
+ assert returncode not in [None, 0]
+ assert runner.returncode == returncode
+ assert runner.process_handler is not None
+ assert runner.wait(1) == returncode
-class MozrunnerStopTestCase(mozrunnertest.MozrunnerTestCase):
-
- def test_stop_process(self):
- """Stop the process and test properties"""
- self.runner.start()
- returncode = self.runner.stop()
+def test_stop_before_start(runner):
+ """Stop the process before it gets started should not raise an error"""
+ runner.stop()
- self.assertFalse(self.runner.is_running())
- self.assertNotIn(returncode, [None, 0])
- self.assertEqual(self.runner.returncode, returncode)
- self.assertIsNotNone(self.runner.process_handler)
-
- self.assertEqual(self.runner.wait(1), returncode)
- def test_stop_before_start(self):
- """Stop the process before it gets started should not raise an error"""
- self.runner.stop()
+def test_stop_process_custom_signal(runner):
+ """Stop the process via a custom signal and test properties"""
+ runner.start()
+ returncode = runner.stop(signal.SIGTERM)
- def test_stop_process_custom_signal(self):
- """Stop the process via a custom signal and test properties"""
- self.runner.start()
- returncode = self.runner.stop(signal.SIGTERM)
-
- self.assertFalse(self.runner.is_running())
- self.assertNotIn(returncode, [None, 0])
- self.assertEqual(self.runner.returncode, returncode)
- self.assertIsNotNone(self.runner.process_handler)
-
- self.assertEqual(self.runner.wait(1), returncode)
+ assert not runner.is_running()
+ assert returncode not in [None, 0]
+ assert runner.returncode == returncode
+ assert runner.process_handler is not None
+ assert runner.wait(1) == returncode
if __name__ == '__main__':
mozunit.main()
--- a/testing/mozbase/mozrunner/tests/test_threads.py
+++ b/testing/mozbase/mozrunner/tests/test_threads.py
@@ -1,81 +1,59 @@
#!/usr/bin/env python
# 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/.
from __future__ import absolute_import
-import threading
-from time import sleep
-
import mozunit
-import mozrunnertest
-
-class RunnerThread(threading.Thread):
+def test_process_start_via_thread(runner, create_thread):
+ """Start the runner via a thread"""
+ thread = create_thread(runner, True, 2)
- def __init__(self, runner, do_start, timeout=10):
- threading.Thread.__init__(self)
- self.runner = runner
- self.timeout = timeout
- self.do_start = do_start
+ thread.start()
+ thread.join()
- def run(self):
- sleep(self.timeout)
- if self.do_start:
- self.runner.start()
- else:
- self.runner.stop()
+ assert runner.is_running()
-class MozrunnerThreadsTestCase(mozrunnertest.MozrunnerTestCase):
-
- def test_process_start_via_thread(self):
- """Start the runner via a thread"""
- thread = RunnerThread(self.runner, True, 2)
- self.threads.append(thread)
-
- thread.start()
- thread.join()
-
- self.assertTrue(self.runner.is_running())
-
- def test_process_stop_via_multiple_threads(self):
- """Stop the runner via multiple threads"""
- self.runner.start()
- for i in range(5):
- thread = RunnerThread(self.runner, False, 5)
- self.threads.append(thread)
- thread.start()
-
- # Wait until the process has been stopped by another thread
- for thread in self.threads:
- thread.join()
- returncode = self.runner.wait(2)
-
- self.assertNotIn(returncode, [None, 0])
- self.assertEqual(self.runner.returncode, returncode)
- self.assertIsNotNone(self.runner.process_handler)
- self.assertEqual(self.runner.wait(10), returncode)
-
- def test_process_post_stop_via_thread(self):
- """Stop the runner and try it again with a thread a bit later"""
- self.runner.start()
- thread = RunnerThread(self.runner, False, 5)
- self.threads.append(thread)
+def test_process_stop_via_multiple_threads(runner, create_thread):
+ """Stop the runner via multiple threads"""
+ runner.start()
+ threads = []
+ for i in range(5):
+ thread = create_thread(runner, False, 5)
+ threads.append(thread)
thread.start()
- # Wait a bit to start the application gets started
- self.runner.wait(2)
- returncode = self.runner.stop()
+ # Wait until the process has been stopped by another thread
+ for thread in threads:
thread.join()
+ returncode = runner.wait(1)
+
+ assert returncode not in [None, 0]
+ assert runner.returncode == returncode
+ assert runner.process_handler is not None
+ assert runner.wait(2) == returncode
+
- self.assertNotIn(returncode, [None, 0])
- self.assertEqual(self.runner.returncode, returncode)
- self.assertIsNotNone(self.runner.process_handler)
- self.assertEqual(self.runner.wait(10), returncode)
+def test_process_post_stop_via_thread(runner, create_thread):
+ """Stop the runner and try it again with a thread a bit later"""
+ runner.start()
+ thread = create_thread(runner, False, 5)
+ thread.start()
+
+ # Wait a bit to start the application gets started
+ runner.wait(1)
+ returncode = runner.stop()
+ thread.join()
+
+ assert returncode not in [None, 0]
+ assert runner.returncode == returncode
+ assert runner.process_handler is not None
+ assert runner.wait(2) == returncode
if __name__ == '__main__':
mozunit.main()
--- a/testing/mozbase/mozrunner/tests/test_wait.py
+++ b/testing/mozbase/mozrunner/tests/test_wait.py
@@ -1,36 +1,34 @@
#!/usr/bin/env python
# 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/.
from __future__ import absolute_import
import mozunit
-import mozrunnertest
-class MozrunnerWaitTestCase(mozrunnertest.MozrunnerTestCase):
+def test_wait_while_running(runner):
+ """Wait for the process while it is running"""
+ runner.start()
+ returncode = runner.wait(1)
- def test_wait_while_running(self):
- """Wait for the process while it is running"""
- self.runner.start()
- returncode = self.runner.wait(1)
+ assert runner.is_running()
+ assert returncode is None
+ assert runner.returncode == returncode
+ assert runner.process_handler is not None
- self.assertTrue(self.runner.is_running())
- self.assertEqual(returncode, None)
- self.assertEqual(self.runner.returncode, returncode)
- self.assertIsNotNone(self.runner.process_handler)
- def test_wait_after_process_finished(self):
- """Bug 965714: wait() after stop should not raise an error"""
- self.runner.start()
- self.runner.process_handler.kill()
+def test_wait_after_process_finished(runner):
+ """Bug 965714: wait() after stop should not raise an error"""
+ runner.start()
+ runner.process_handler.kill()
- returncode = self.runner.wait(1)
+ returncode = runner.wait(1)
- self.assertNotIn(returncode, [None, 0])
- self.assertIsNotNone(self.runner.process_handler)
+ assert returncode not in [None, 0]
+ assert runner.process_handler is not None
if __name__ == '__main__':
mozunit.main()