diff --git a/swiftclient/multithreading.py b/swiftclient/multithreading.py
index a2dcd719..ade0f7bb 100644
--- a/swiftclient/multithreading.py
+++ b/swiftclient/multithreading.py
@@ -86,6 +86,9 @@ class OutputManager(object):
             msg = msg % fmt_args
         self.error_print_pool.submit(self._print_error, msg)
 
+    def get_error_count(self):
+        return self.error_count
+
     def _print(self, item, stream=None):
         if stream is None:
             stream = self.print_stream
diff --git a/swiftclient/shell.py b/swiftclient/shell.py
index 8d4da67b..d58de60f 100755
--- a/swiftclient/shell.py
+++ b/swiftclient/shell.py
@@ -1303,7 +1303,7 @@ Examples:
         except (ClientException, RequestException, socket.error) as err:
             output.error(str(err))
 
-    if output.error_count > 0:
+    if output.get_error_count() > 0:
         exit(1)
 
 
diff --git a/tests/unit/test_shell.py b/tests/unit/test_shell.py
index 617fba22..f73ed14a 100644
--- a/tests/unit/test_shell.py
+++ b/tests/unit/test_shell.py
@@ -17,6 +17,7 @@ import mock
 import os
 import tempfile
 import unittest
+from testtools import ExpectedException
 
 import six
 
@@ -88,9 +89,8 @@ class TestShell(unittest.TestCase):
         except OSError:
             pass
 
-    @mock.patch('swiftclient.shell.OutputManager._print')
     @mock.patch('swiftclient.service.Connection')
-    def test_stat_account(self, connection, mock_print):
+    def test_stat_account(self, connection):
         argv = ["", "stat"]
         return_headers = {
             'x-account-container-count': '1',
@@ -100,16 +100,17 @@ class TestShell(unittest.TestCase):
             'date': ''}
         connection.return_value.head_account.return_value = return_headers
         connection.return_value.url = 'http://127.0.0.1/v1/AUTH_account'
-        swiftclient.shell.main(argv)
-        calls = [mock.call('   Account: AUTH_account\n' +
-                           'Containers: 1\n' +
-                           '   Objects: 2\n' +
-                           '     Bytes: 3')]
-        mock_print.assert_has_calls(calls)
+        with CaptureOutput() as output:
+            swiftclient.shell.main(argv)
+
+            self.assertEquals(output.out,
+                              '   Account: AUTH_account\n'
+                              'Containers: 1\n'
+                              '   Objects: 2\n'
+                              '     Bytes: 3\n')
 
-    @mock.patch('swiftclient.shell.OutputManager._print')
     @mock.patch('swiftclient.service.Connection')
-    def test_stat_container(self, connection, mock_print):
+    def test_stat_container(self, connection):
         return_headers = {
             'x-container-object-count': '1',
             'x-container-bytes-used': '2',
@@ -121,20 +122,21 @@ class TestShell(unittest.TestCase):
         argv = ["", "stat", "container"]
         connection.return_value.head_container.return_value = return_headers
         connection.return_value.url = 'http://127.0.0.1/v1/AUTH_account'
-        swiftclient.shell.main(argv)
-        calls = [mock.call('  Account: AUTH_account\n' +
-                           'Container: container\n' +
-                           '  Objects: 1\n' +
-                           '    Bytes: 2\n' +
-                           ' Read ACL: test2:tester2\n' +
-                           'Write ACL: test3:tester3\n' +
-                           '  Sync To: other\n' +
-                           ' Sync Key: secret')]
-        mock_print.assert_has_calls(calls)
+        with CaptureOutput() as output:
+            swiftclient.shell.main(argv)
+
+            self.assertEquals(output.out,
+                              '  Account: AUTH_account\n'
+                              'Container: container\n'
+                              '  Objects: 1\n'
+                              '    Bytes: 2\n'
+                              ' Read ACL: test2:tester2\n'
+                              'Write ACL: test3:tester3\n'
+                              '  Sync To: other\n'
+                              ' Sync Key: secret\n')
 
-    @mock.patch('swiftclient.shell.OutputManager._print')
     @mock.patch('swiftclient.service.Connection')
-    def test_stat_object(self, connection, mock_print):
+    def test_stat_object(self, connection):
         return_headers = {
             'x-object-manifest': 'manifest',
             'etag': 'md5',
@@ -145,20 +147,22 @@ class TestShell(unittest.TestCase):
         argv = ["", "stat", "container", "object"]
         connection.return_value.head_object.return_value = return_headers
         connection.return_value.url = 'http://127.0.0.1/v1/AUTH_account'
-        swiftclient.shell.main(argv)
-        calls = [mock.call('       Account: AUTH_account\n' +
-                           '     Container: container\n' +
-                           '        Object: object\n' +
-                           '  Content Type: text/plain\n' +
-                           'Content Length: 42\n' +
-                           ' Last Modified: yesterday\n' +
-                           '          ETag: md5\n' +
-                           '      Manifest: manifest')]
-        mock_print.assert_has_calls(calls)
 
-    @mock.patch('swiftclient.shell.OutputManager._print')
+        with CaptureOutput() as output:
+            swiftclient.shell.main(argv)
+
+            self.assertEquals(output.out,
+                              '       Account: AUTH_account\n'
+                              '     Container: container\n'
+                              '        Object: object\n'
+                              '  Content Type: text/plain\n'
+                              'Content Length: 42\n'
+                              ' Last Modified: yesterday\n'
+                              '          ETag: md5\n'
+                              '      Manifest: manifest\n')
+
     @mock.patch('swiftclient.service.Connection')
-    def test_list_account(self, connection, mock_print):
+    def test_list_account(self, connection):
         # Test account listing
         connection.return_value.get_account.side_effect = [
             [None, [{'name': 'container'}]],
@@ -166,16 +170,17 @@ class TestShell(unittest.TestCase):
         ]
 
         argv = ["", "list"]
-        swiftclient.shell.main(argv)
-        calls = [mock.call(marker='', prefix=None),
-                 mock.call(marker='container', prefix=None)]
-        connection.return_value.get_account.assert_has_calls(calls)
-        calls = [mock.call('container')]
-        mock_print.assert_has_calls(calls)
 
-    @mock.patch('swiftclient.shell.OutputManager._print')
+        with CaptureOutput() as output:
+            swiftclient.shell.main(argv)
+            calls = [mock.call(marker='', prefix=None),
+                     mock.call(marker='container', prefix=None)]
+            connection.return_value.get_account.assert_has_calls(calls)
+
+            self.assertEquals(output.out, 'container\n')
+
     @mock.patch('swiftclient.service.Connection')
-    def test_list_account_long(self, connection, mock_print):
+    def test_list_account_long(self, connection):
         # Test account listing
         connection.return_value.get_account.side_effect = [
             [None, [{'name': 'container', 'bytes': 0, 'count': 0}]],
@@ -183,13 +188,15 @@ class TestShell(unittest.TestCase):
         ]
 
         argv = ["", "list", "--lh"]
-        swiftclient.shell.main(argv)
-        calls = [mock.call(marker='', prefix=None),
-                 mock.call(marker='container', prefix=None)]
-        connection.return_value.get_account.assert_has_calls(calls)
-        calls = [mock.call('    0    0 1970-01-01 00:00:01 container'),
-                 mock.call('    0    0')]
-        mock_print.assert_has_calls(calls)
+        with CaptureOutput() as output:
+            swiftclient.shell.main(argv)
+            calls = [mock.call(marker='', prefix=None),
+                     mock.call(marker='container', prefix=None)]
+            connection.return_value.get_account.assert_has_calls(calls)
+
+            self.assertEquals(output.out,
+                              '    0    0 1970-01-01 00:00:01 container\n'
+                              '    0    0\n')
 
         # Now test again, this time without returning metadata
         connection.return_value.head_container.return_value = {}
@@ -201,30 +208,32 @@ class TestShell(unittest.TestCase):
         ]
 
         argv = ["", "list", "--lh"]
-        swiftclient.shell.main(argv)
-        calls = [mock.call(marker='', prefix=None),
-                 mock.call(marker='container', prefix=None)]
-        connection.return_value.get_account.assert_has_calls(calls)
-        calls = [mock.call('    0    0 ????-??-?? ??:??:?? container'),
-                 mock.call('    0    0')]
-        mock_print.assert_has_calls(calls)
+        with CaptureOutput() as output:
+            swiftclient.shell.main(argv)
+            calls = [mock.call(marker='', prefix=None),
+                     mock.call(marker='container', prefix=None)]
+            connection.return_value.get_account.assert_has_calls(calls)
+
+            self.assertEquals(output.out,
+                              '    0    0 ????-??-?? ??:??:?? container\n'
+                              '    0    0\n')
 
-    @mock.patch('swiftclient.shell.OutputManager._print')
     @mock.patch('swiftclient.service.Connection')
-    def test_list_container(self, connection, mock_print):
+    def test_list_container(self, connection):
         connection.return_value.get_container.side_effect = [
             [None, [{'name': 'object_a'}]],
             [None, []],
         ]
         argv = ["", "list", "container"]
-        swiftclient.shell.main(argv)
-        calls = [
-            mock.call('container', marker='', delimiter=None, prefix=None),
-            mock.call('container', marker='object_a',
-                      delimiter=None, prefix=None)]
-        connection.return_value.get_container.assert_has_calls(calls)
-        calls = [mock.call('object_a')]
-        mock_print.assert_has_calls(calls)
+        with CaptureOutput() as output:
+            swiftclient.shell.main(argv)
+            calls = [
+                mock.call('container', marker='', delimiter=None, prefix=None),
+                mock.call('container', marker='object_a',
+                          delimiter=None, prefix=None)]
+            connection.return_value.get_container.assert_has_calls(calls)
+
+            self.assertEquals(output.out, 'object_a\n')
 
         # Test container listing with --long
         connection.return_value.get_container.side_effect = [
@@ -233,16 +242,17 @@ class TestShell(unittest.TestCase):
             [None, []],
         ]
         argv = ["", "list", "container", "--long"]
-        swiftclient.shell.main(argv)
-        calls = [
-            mock.call('container', marker='', delimiter=None, prefix=None),
-            mock.call('container', marker='object_a',
-                      delimiter=None, prefix=None)]
-        connection.return_value.get_container.assert_has_calls(calls)
-        calls = [mock.call('object_a'),
-                 mock.call('           0        123      456 object_a'),
-                 mock.call('           0')]
-        mock_print.assert_has_calls(calls)
+        with CaptureOutput() as output:
+            swiftclient.shell.main(argv)
+            calls = [
+                mock.call('container', marker='', delimiter=None, prefix=None),
+                mock.call('container', marker='object_a',
+                          delimiter=None, prefix=None)]
+            connection.return_value.get_container.assert_has_calls(calls)
+
+            self.assertEquals(output.out,
+                              '           0        123      456 object_a\n'
+                              '           0\n')
 
     @mock.patch('swiftclient.service.makedirs')
     @mock.patch('swiftclient.service.Connection')
@@ -449,23 +459,29 @@ class TestShell(unittest.TestCase):
         connection.return_value.post_account.assert_called_with(
             headers={}, response_dict={})
 
-    @mock.patch('swiftclient.shell.OutputManager.error')
     @mock.patch('swiftclient.service.Connection')
-    def test_post_account_bad_auth(self, connection, error):
+    def test_post_account_bad_auth(self, connection):
         argv = ["", "post"]
         connection.return_value.post_account.side_effect = \
             swiftclient.ClientException('bad auth')
-        swiftclient.shell.main(argv)
-        error.assert_called_with('bad auth')
 
-    @mock.patch('swiftclient.shell.OutputManager.error')
+        with CaptureOutput() as output:
+            with ExpectedException(SystemExit):
+                swiftclient.shell.main(argv)
+
+            self.assertEquals(output.err, 'bad auth\n')
+
     @mock.patch('swiftclient.service.Connection')
-    def test_post_account_not_found(self, connection, error):
+    def test_post_account_not_found(self, connection):
         argv = ["", "post"]
         connection.return_value.post_account.side_effect = \
             swiftclient.ClientException('test', http_status=404)
-        swiftclient.shell.main(argv)
-        error.assert_called_with('Account not found')
+
+        with CaptureOutput() as output:
+            with ExpectedException(SystemExit):
+                swiftclient.shell.main(argv)
+
+            self.assertEquals(output.err, 'Account not found\n')
 
     @mock.patch('swiftclient.service.Connection')
     def test_post_container(self, connection):
@@ -474,14 +490,17 @@ class TestShell(unittest.TestCase):
         connection.return_value.post_container.assert_called_with(
             'container', headers={}, response_dict={})
 
-    @mock.patch('swiftclient.shell.OutputManager.error')
     @mock.patch('swiftclient.service.Connection')
-    def test_post_container_bad_auth(self, connection, error):
+    def test_post_container_bad_auth(self, connection):
         argv = ["", "post", "container"]
         connection.return_value.post_container.side_effect = \
             swiftclient.ClientException('bad auth')
-        swiftclient.shell.main(argv)
-        error.assert_called_with('bad auth')
+
+        with CaptureOutput() as output:
+            with ExpectedException(SystemExit):
+                swiftclient.shell.main(argv)
+
+            self.assertEquals(output.err, 'bad auth\n')
 
     @mock.patch('swiftclient.service.Connection')
     def test_post_container_not_found_causes_put(self, connection):
@@ -492,12 +511,14 @@ class TestShell(unittest.TestCase):
         self.assertEqual('container',
                          connection.return_value.put_container.call_args[0][0])
 
-    @mock.patch('swiftclient.shell.OutputManager.error')
-    def test_post_container_with_bad_name(self, error):
+    def test_post_container_with_bad_name(self):
         argv = ["", "post", "conta/iner"]
-        swiftclient.shell.main(argv)
-        self.assertTrue(error.called)
-        self.assertTrue(error.call_args[0][0].startswith('WARNING: / in'))
+
+        with CaptureOutput() as output:
+            with ExpectedException(SystemExit):
+                swiftclient.shell.main(argv)
+            self.assertTrue(output.err != '')
+            self.assertTrue(output.err.startswith('WARNING: / in'))
 
     @mock.patch('swiftclient.service.Connection')
     def test_post_container_with_options(self, connection):
@@ -527,21 +548,27 @@ class TestShell(unittest.TestCase):
                 'Content-Type': 'text/plain',
                 'X-Object-Meta-Color': 'Blue'}, response_dict={})
 
-    @mock.patch('swiftclient.shell.OutputManager.error')
     @mock.patch('swiftclient.service.Connection')
-    def test_post_object_bad_auth(self, connection, error):
+    def test_post_object_bad_auth(self, connection):
         argv = ["", "post", "container", "object"]
         connection.return_value.post_object.side_effect = \
             swiftclient.ClientException("bad auth")
-        swiftclient.shell.main(argv)
-        error.assert_called_with('bad auth')
 
-    @mock.patch('swiftclient.shell.OutputManager.error')
-    def test_post_object_too_many_args(self, error):
+        with CaptureOutput() as output:
+            with ExpectedException(SystemExit):
+                swiftclient.shell.main(argv)
+
+            self.assertEquals(output.err, 'bad auth\n')
+
+    def test_post_object_too_many_args(self):
         argv = ["", "post", "container", "object", "bad_arg"]
-        swiftclient.shell.main(argv)
-        self.assertTrue(error.called)
-        self.assertTrue(error.call_args[0][0].startswith('Usage'))
+
+        with CaptureOutput() as output:
+            with ExpectedException(SystemExit):
+                swiftclient.shell.main(argv)
+
+            self.assertTrue(output.err != '')
+            self.assertTrue(output.err.startswith('Usage'))
 
     @mock.patch('swiftclient.shell.generate_temp_url')
     def test_temp_url(self, temp_url):
@@ -565,15 +592,9 @@ class TestShell(unittest.TestCase):
             actual = x.call_args_list[-1][1]["options"]["segment_size"]
             self.assertEqual(int(actual), expected)
 
-        mock_out = mock.MagicMock(spec=swiftclient.shell.OutputManager)
-        mock_out.__enter__.return_value = mock_out
-        mock_out.return_value = mock_out
-        type(mock_out).error_count = mock.PropertyMock(return_value=0)
-
         mock_swift = mock.MagicMock(spec=swiftclient.shell.SwiftService)
-
         with mock.patch("swiftclient.shell.SwiftService", mock_swift):
-            with mock.patch('swiftclient.shell.OutputManager', mock_out):
+            with CaptureOutput(suppress_systemexit=True) as output:
                 # Test new behaviour with both upper and lower case
                 # trailing characters
                 argv = ["", "upload", "-S", "1B", "container", "object"]
@@ -597,18 +618,24 @@ class TestShell(unittest.TestCase):
                 swiftclient.shell.main(argv)
                 _check_expected(mock_swift, 12345)
 
-                # Test invalid states
-                argv = ["", "upload", "-S", "1234X", "container", "object"]
-                swiftclient.shell.main(argv)
-                mock_out.error.assert_called_with("Invalid segment size")
+            with CaptureOutput() as output:
+                with ExpectedException(SystemExit):
+                    #  Test invalid states
+                    argv = ["", "upload", "-S", "1234X", "container", "object"]
+                    swiftclient.shell.main(argv)
+                self.assertEquals(output.err, "Invalid segment size\n")
+                output.clear()
 
-                argv = ["", "upload", "-S", "K1234", "container", "object"]
-                swiftclient.shell.main(argv)
-                mock_out.error.assert_called_with("Invalid segment size")
+                with ExpectedException(SystemExit):
+                    argv = ["", "upload", "-S", "K1234", "container", "object"]
+                    swiftclient.shell.main(argv)
+                self.assertEquals(output.err, "Invalid segment size\n")
+                output.clear()
 
-                argv = ["", "upload", "-S", "K", "container", "object"]
-                swiftclient.shell.main(argv)
-                mock_out.error.assert_called_with("Invalid segment size")
+                with ExpectedException(SystemExit):
+                    argv = ["", "upload", "-S", "K", "container", "object"]
+                    swiftclient.shell.main(argv)
+                self.assertEquals(output.err, "Invalid segment size\n")
 
 
 class TestSubcommandHelp(unittest.TestCase):
diff --git a/tests/unit/utils.py b/tests/unit/utils.py
index 3cbb1606..88a214d3 100644
--- a/tests/unit/utils.py
+++ b/tests/unit/utils.py
@@ -238,17 +238,29 @@ class CaptureStream(object):
     def getvalue(self):
         return self._capture.getvalue()
 
+    def clear(self):
+        self._capture.truncate(0)
+        self._capture.seek(0)
+
 
 class CaptureOutput(object):
 
-    def __init__(self):
+    def __init__(self, suppress_systemexit=False):
         self._out = CaptureStream(sys.stdout)
         self._err = CaptureStream(sys.stderr)
+        self.patchers = []
 
         WrappedOutputManager = functools.partial(s.OutputManager,
                                                  print_stream=self._out,
                                                  error_stream=self._err)
-        self.patchers = [
+
+        if suppress_systemexit:
+            self.patchers += [
+                mock.patch('swiftclient.shell.OutputManager.get_error_count',
+                           return_value=0)
+            ]
+
+        self.patchers += [
             mock.patch('swiftclient.shell.OutputManager',
                        WrappedOutputManager),
             mock.patch('sys.stdout', self._out),
@@ -272,6 +284,10 @@ class CaptureOutput(object):
     def err(self):
         return self._err.getvalue()
 
+    def clear(self):
+        self._out.clear()
+        self._err.clear()
+
     # act like the string captured by stdout
 
     def __str__(self):