Buffer unittests to avoid output to build log (#1070)

Requires use of a context manager within each test method for stdout/stderr patches, rather than the @patch.object decorator. Otherwise, the test runner hijacks the patched object before the method under test can use it.

Note: The `--buffer` switch in the unittest module will suppress all
output during the test, unless the test fails. However, with this implementation, anything that would have been printed to the streams within
the context manager will not be reflected in the test runner's output,
should the test fail.

See more in jay0lee/GAM#1068
This commit is contained in:
ejochman
2020-01-04 10:24:07 -08:00
committed by Jay Lee
parent bb5eab886d
commit 12c0b33cf1
4 changed files with 62 additions and 66 deletions

View File

@@ -196,8 +196,8 @@ install:
- source src/travis/$TRAVIS_OS_NAME-$PLATFORM-install.sh
script:
# Discover and run all Python unit tests
- $python -m unittest discover -s ./ -p "*_test.py"
# Discover and run all Python unit tests. Buffer output so that it's not sent to the build log.
- $python -m unittest discover --start-directory ./ --pattern "*_test.py" --buffer
- $gam version extended
- $gam version | grep travis # travis should be part of the path (not /tmp or such)
# determine which Python version GAM is built with and ensure it's at least build version from above.

View File

@@ -86,23 +86,21 @@ class ControlFlowTest(unittest.TestCase):
# Prevent the system from actually sleeping and thus slowing down the test.
@patch.object(controlflow.time, 'sleep')
@patch.object(controlflow.sys.stderr, 'write')
def test_wait_on_failure_prints_errors(self, mock_stderr_write,
unused_mock_sleep):
def test_wait_on_failure_prints_errors(self, unused_mock_sleep):
message = 'An error message to display'
controlflow.wait_on_failure(1, 5, message, error_print_threshold=0)
with patch.object(controlflow.sys.stderr, 'write') as mock_stderr_write:
controlflow.wait_on_failure(1, 5, message, error_print_threshold=0)
self.assertIn(message, mock_stderr_write.call_args[0][0])
@patch.object(controlflow.time, 'sleep')
@patch.object(controlflow.sys.stderr, 'write')
def test_wait_on_failure_only_prints_after_threshold(self, mock_stderr_write,
unused_mock_sleep):
def test_wait_on_failure_only_prints_after_threshold(self, unused_mock_sleep):
total_attempts = 5
threshold = 3
for attempt in range(1, total_attempts + 1):
controlflow.wait_on_failure(
attempt,
total_attempts,
'Attempt #%s' % attempt,
error_print_threshold=threshold)
with patch.object(controlflow.sys.stderr, 'write') as mock_stderr_write:
for attempt in range(1, total_attempts + 1):
controlflow.wait_on_failure(
attempt,
total_attempts,
'Attempt #%s' % attempt,
error_print_threshold=threshold)
self.assertEqual(total_attempts - threshold, mock_stderr_write.call_count)

View File

@@ -10,50 +10,50 @@ from var import WARNING_PREFIX
class DisplayTest(unittest.TestCase):
@patch.object(display.sys.stderr, 'write')
def test_print_error_prints_to_stderr(self, mock_write):
def test_print_error_prints_to_stderr(self):
message = 'test error'
display.print_error(message)
with patch.object(display.sys.stderr, 'write') as mock_write:
display.print_error(message)
printed_message = mock_write.call_args[0][0]
self.assertIn(message, printed_message)
@patch.object(display.sys.stderr, 'write')
def test_print_error_prints_error_prefix(self, mock_write):
def test_print_error_prints_error_prefix(self):
message = 'test error'
display.print_error(message)
with patch.object(display.sys.stderr, 'write') as mock_write:
display.print_error(message)
printed_message = mock_write.call_args[0][0]
self.assertLess(
printed_message.find(ERROR_PREFIX), printed_message.find(message),
'The error prefix does not appear before the error message')
@patch.object(display.sys.stderr, 'write')
def test_print_error_ends_message_with_newline(self, mock_write):
def test_print_error_ends_message_with_newline(self):
message = 'test error'
display.print_error(message)
with patch.object(display.sys.stderr, 'write') as mock_write:
display.print_error(message)
printed_message = mock_write.call_args[0][0]
self.assertRegex(printed_message, '\n$',
'The error message does not end in a newline.')
@patch.object(display.sys.stderr, 'write')
def test_print_warning_prints_to_stderr(self, mock_write):
def test_print_warning_prints_to_stderr(self):
message = 'test warning'
display.print_warning(message)
with patch.object(display.sys.stderr, 'write') as mock_write:
display.print_error(message)
printed_message = mock_write.call_args[0][0]
self.assertIn(message, printed_message)
@patch.object(display.sys.stderr, 'write')
def test_print_warning_prints_error_prefix(self, mock_write):
def test_print_warning_prints_error_prefix(self):
message = 'test warning'
display.print_error(message)
with patch.object(display.sys.stderr, 'write') as mock_write:
display.print_error(message)
printed_message = mock_write.call_args[0][0]
self.assertLess(
printed_message.find(WARNING_PREFIX), printed_message.find(message),
'The warning prefix does not appear before the error message')
@patch.object(display.sys.stderr, 'write')
def test_print_warning_ends_message_with_newline(self, mock_write):
def test_print_warning_ends_message_with_newline(self):
message = 'test warning'
display.print_error(message)
with patch.object(display.sys.stderr, 'write') as mock_write:
display.print_error(message)
printed_message = mock_write.call_args[0][0]
self.assertRegex(printed_message, '\n$',
'The warning message does not end in a newline.')

View File

@@ -361,25 +361,25 @@ class GapiTest(unittest.TestCase):
self.assertIn('pageSize', request_method_kwargs)
self.assertEqual(123456, request_method_kwargs['pageSize'])
@patch.object(gapi.sys.stderr, 'write')
def test_get_all_pages_prints_paging_message(self, mock_write):
def test_get_all_pages_prints_paging_message(self):
self.mock_method.return_value.execute.side_effect = self.simple_3_page_response
paging_message = 'A simple string displayed during paging'
gapi.get_all_pages(
self.mock_service, self.mock_method_name, page_message=paging_message)
with patch.object(gapi.sys.stderr, 'write') as mock_write:
gapi.get_all_pages(
self.mock_service, self.mock_method_name, page_message=paging_message)
messages_written = [
call_args[0][0] for call_args in mock_write.call_args_list
]
self.assertIn(paging_message, messages_written)
@patch.object(gapi.sys.stderr, 'write')
def test_get_all_pages_prints_paging_message_inline(self, mock_write):
def test_get_all_pages_prints_paging_message_inline(self):
self.mock_method.return_value.execute.side_effect = self.simple_3_page_response
paging_message = 'A simple string displayed during paging'
gapi.get_all_pages(
self.mock_service, self.mock_method_name, page_message=paging_message)
with patch.object(gapi.sys.stderr, 'write') as mock_write:
gapi.get_all_pages(
self.mock_service, self.mock_method_name, page_message=paging_message)
messages_written = [
call_args[0][0] for call_args in mock_write.call_args_list
]
@@ -394,13 +394,13 @@ class GapiTest(unittest.TestCase):
paging_message_call_positions[0]:paging_message_call_positions[1]]
self.assertIn('\r', printed_between_page_messages)
@patch.object(gapi.sys.stderr, 'write')
def test_get_all_pages_ends_paging_message_with_newline(self, mock_write):
def test_get_all_pages_ends_paging_message_with_newline(self):
self.mock_method.return_value.execute.side_effect = self.simple_3_page_response
paging_message = 'A simple string displayed during paging'
gapi.get_all_pages(
self.mock_service, self.mock_method_name, page_message=paging_message)
with patch.object(gapi.sys.stderr, 'write') as mock_write:
gapi.get_all_pages(
self.mock_service, self.mock_method_name, page_message=paging_message)
messages_written = [
call_args[0][0] for call_args in mock_write.call_args_list
]
@@ -410,14 +410,13 @@ class GapiTest(unittest.TestCase):
messages_written) - messages_written[::-1].index('\r\n')
self.assertGreater(last_carriage_return_index, last_page_message_index)
@patch.object(gapi.sys.stderr, 'write')
def test_get_all_pages_prints_attribute_total_items_in_paging_message(
self, mock_write):
def test_get_all_pages_prints_attribute_total_items_in_paging_message(self):
self.mock_method.return_value.execute.side_effect = self.simple_3_page_response
paging_message = 'Total number of items discovered: %%total_items%%'
gapi.get_all_pages(
self.mock_service, self.mock_method_name, page_message=paging_message)
with patch.object(gapi.sys.stderr, 'write') as mock_write:
gapi.get_all_pages(
self.mock_service, self.mock_method_name, page_message=paging_message)
messages_written = [
call_args[0][0] for call_args in mock_write.call_args_list
@@ -442,17 +441,17 @@ class GapiTest(unittest.TestCase):
for message in messages_written:
self.assertNotIn('%%total_items', message)
@patch.object(gapi.sys.stderr, 'write')
def test_get_all_pages_prints_attribute_first_item_in_paging_message(
self, mock_write):
def test_get_all_pages_prints_attribute_first_item_in_paging_message(self):
self.mock_method.return_value.execute.side_effect = self.simple_3_page_response
paging_message = 'First item in page: %%first_item%%'
gapi.get_all_pages(
self.mock_service,
self.mock_method_name,
page_message=paging_message,
message_attribute='position')
with patch.object(gapi.sys.stderr, 'write') as mock_write:
gapi.get_all_pages(
self.mock_service,
self.mock_method_name,
page_message=paging_message,
message_attribute='position')
messages_written = [
call_args[0][0] for call_args in mock_write.call_args_list
@@ -471,17 +470,16 @@ class GapiTest(unittest.TestCase):
for message in messages_written:
self.assertNotIn('%%first_item', message)
@patch.object(gapi.sys.stderr, 'write')
def test_get_all_pages_prints_attribute_last_item_in_paging_message(
self, mock_write):
def test_get_all_pages_prints_attribute_last_item_in_paging_message(self):
self.mock_method.return_value.execute.side_effect = self.simple_3_page_response
paging_message = 'Last item in page: %%last_item%%'
gapi.get_all_pages(
self.mock_service,
self.mock_method_name,
page_message=paging_message,
message_attribute='position')
with patch.object(gapi.sys.stderr, 'write') as mock_write:
gapi.get_all_pages(
self.mock_service,
self.mock_method_name,
page_message=paging_message,
message_attribute='position')
messages_written = [
call_args[0][0] for call_args in mock_write.call_args_list