Use mock instead of relying on command stderr
CLI execute tests execute a command with an invalid option name and
expect the option name to be echoed back. The output of the command
is not platform independent, it is different for instance on macosx.
Actually invoking the command is not a good practise in unit
tests as even in positive case the command may be installed in a
different path or have a different output.
Changing the tests so that they use mock on subprocess.Popen instead.
Closes-bug 1583205
Change-Id: I9c509359250d2eeb8942e1335e9f3d769e84415a
diff --git a/tempest/tests/lib/cli/test_execute.py b/tempest/tests/lib/cli/test_execute.py
index b846c46..cc9c94c 100644
--- a/tempest/tests/lib/cli/test_execute.py
+++ b/tempest/tests/lib/cli/test_execute.py
@@ -12,26 +12,65 @@
# under the License.
+import mock
+import subprocess
+
from tempest.lib.cli import base as cli_base
from tempest.lib import exceptions
from tempest.tests import base
class TestExecute(base.TestCase):
- def test_execute_success(self):
+
+ @mock.patch('subprocess.Popen', autospec=True)
+ def test_execute_success(self, mock_popen):
+ mock_popen.return_value.returncode = 0
+ mock_popen.return_value.communicate.return_value = (
+ "__init__.py", "")
result = cli_base.execute("/bin/ls", action="tempest",
flags="-l -a")
+ args, kwargs = mock_popen.call_args
+ # Check merge_stderr == False
+ self.assertEqual(subprocess.PIPE, kwargs['stderr'])
+ # Check action and flags are passed
+ args = args[0]
+ # We just tests that all pieces are passed through, we cannot make
+ # assumptions about the order
+ self.assertIn("/bin/ls", args)
+ self.assertIn("-l", args)
+ self.assertIn("-a", args)
+ self.assertIn("tempest", args)
+ # The result is mocked - checking that the mock was invoked correctly
self.assertIsInstance(result, str)
self.assertIn("__init__.py", result)
- def test_execute_failure(self):
+ @mock.patch('subprocess.Popen', autospec=True)
+ def test_execute_failure(self, mock_popen):
+ mock_popen.return_value.returncode = 1
+ mock_popen.return_value.communicate.return_value = (
+ "No such option --foobar", "")
result = cli_base.execute("/bin/ls", action="tempest.lib",
flags="--foobar", merge_stderr=True,
fail_ok=True)
+ args, kwargs = mock_popen.call_args
+ # Check the merge_stderr
+ self.assertEqual(subprocess.STDOUT, kwargs['stderr'])
+ # Check action and flags are passed
+ args = args[0]
+ # We just tests that all pieces are passed through, we cannot make
+ # assumptions about the order
+ self.assertIn("/bin/ls", args)
+ self.assertIn("--foobar", args)
+ self.assertIn("tempest.lib", args)
+ # The result is mocked - checking that the mock was invoked correctly
self.assertIsInstance(result, str)
self.assertIn("--foobar", result)
- def test_execute_failure_raise_exception(self):
+ @mock.patch('subprocess.Popen', autospec=True)
+ def test_execute_failure_raise_exception(self, mock_popen):
+ mock_popen.return_value.returncode = 1
+ mock_popen.return_value.communicate.return_value = (
+ "No such option --foobar", "")
self.assertRaises(exceptions.CommandFailed, cli_base.execute,
"/bin/ls", action="tempest", flags="--foobar",
merge_stderr=True)