From c3ddf38d53a989766e077b2536c2e20c17dd24b5 Mon Sep 17 00:00:00 2001 From: LorenzoFerraces Date: Wed, 14 Feb 2024 16:30:05 -0300 Subject: [PATCH] added test changes to test_misc_utils, test_system and test_tpo_common back --- mezcla/tests/test_misc_utils.py | 128 ++++++++++++++++++--------- mezcla/tests/test_system.py | 68 +++++++------- mezcla/tests/test_tpo_common.py | 151 +++++++++++++++++++++++--------- 3 files changed, 236 insertions(+), 111 deletions(-) diff --git a/mezcla/tests/test_misc_utils.py b/mezcla/tests/test_misc_utils.py index a86918c6..b10b4b0d 100755 --- a/mezcla/tests/test_misc_utils.py +++ b/mezcla/tests/test_misc_utils.py @@ -12,37 +12,39 @@ """Tests for misc_utils module""" # Standard packages -## TODO: from collections import defaultdict +import math +import datetime +import time +## NOTE: this is empty for now # Installed packages import pytest # Local packages -from mezcla.unittest_wrapper import TestWrapper from mezcla import glue_helpers as gh from mezcla import debug from mezcla import system +from mezcla.unittest_wrapper import TestWrapper # Note: Two references are used for the module to be tested: -# THE_MODULE: global module object -# TestIt.script_module: path to file +# THE_MODULE: global module object import mezcla.misc_utils as THE_MODULE # Make sure more_itertools available -has_more_itertools = True +HAS_MORE_ITERTOOLS = True try: import more_itertools -except: +except ImportError: system.print_exception_info("more_itertools import") - has_more_itertools = False + HAS_MORE_ITERTOOLS = False class TestMiscUtils(TestWrapper): """Class for test case definitions""" - script_module = TestWrapper.get_testing_module_name(__file__, THE_MODULE) def test_transitive_closure(self): """Ensure transitive_closure works as expected""" debug.trace(4, "test_transitive_closure()") + actual = THE_MODULE.transitive_closure([(1, 2), (2, 3), (3, 4)]) expected = set([(1, 2), (1, 3), (1, 4), (2, 3), (3, 4), (2, 4)]) assert actual == expected @@ -58,7 +60,7 @@ def test_read_tabular_data(self): 'language': 'Python\n', 'framework': 'Pytest\n', } - temp_file = gh.get_temp_file() + temp_file = self.get_temp_file() gh.write_file(temp_file, string_table) assert THE_MODULE.read_tabular_data(temp_file) == dict_table @@ -71,7 +73,7 @@ def test_is_prime(self): """Ensure is_prime works as expected""" debug.trace(4, "test_is_prime()") - FIRST_100_PRIMES = [ + first_100_primes = [ 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, @@ -84,13 +86,14 @@ def test_is_prime(self): 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, ] - assert all(THE_MODULE.is_prime(n) for n in FIRST_100_PRIMES) - assert all((not THE_MODULE.is_prime(n)) for n in range(FIRST_100_PRIMES[-1]) if n not in FIRST_100_PRIMES) + + assert all(THE_MODULE.is_prime(n) for n in first_100_primes) + assert all((not THE_MODULE.is_prime(n)) for n in range(first_100_primes[-1]) if n not in first_100_primes) def test_fibonacci(self): """Ensure fibonacci works as expected""" debug.trace(4, "test_fibonacci()") - self.do_assert(not THE_MODULE.fibonacci(-5)) + assert not THE_MODULE.fibonacci(-5) assert THE_MODULE.fibonacci(1) == [0] assert THE_MODULE.fibonacci(10) == [0, 1, 1, 2, 3, 5, 8] @@ -124,11 +127,13 @@ def test_unzip(self): assert THE_MODULE.unzip(zip(), 4) == [[], [], [], []] assert THE_MODULE.unzip(zip(), 4) != [[], []] - @pytest.mark.xfail # TODO: remove xfail def test_get_current_frame(self): """Ensure get_current_frame works as expected""" debug.trace(4, "test_get_current_frame()") - self.do_assert(False, "TODO: code the test") + stack = str(THE_MODULE.get_current_frame()) + test_name = system.get_current_function_name() + assert f'code {test_name}' in stack + assert __file__ in stack def test_eval_expression(self): """Ensure eval_expression works as expected""" @@ -141,25 +146,19 @@ def test_trace_named_object(self): debug.trace(4, "test_trace_named_object()") # With level -1 we ensure that the trace will be printed THE_MODULE.trace_named_object(-1, "sys.argv") - ## OLD - ## captured = capsys.readouterr() - ## assert "sys.argv" in captured.err - self.do_assert("sys.argv" in self.get_stderr()) + captured = self.get_stderr() + assert "sys.argv" in captured def test_trace_named_objects(self): """Ensure trace_named_objects works as expected""" debug.trace(4, "test_trace_named_objects()") # With level -1 we ensure that the trace will be printed THE_MODULE.trace_named_objects(-1, "[len(sys.argv), sys.argv]") - ## OLD: - ## captured = capsys.readouterr() - ## assert "len(sys.argv)" in captured.err - ## assert "sys.argv" in captured.err - stderr = self.get_stderr() - self.do_assert("len(sys.argv)" in stderr) - self.do_assert("sys.argv" in stderr) - - @pytest.mark.skipif(not has_more_itertools, reason="Unable to load more_itertools") + captured = self.get_stderr() + assert "len(sys.argv)" in captured + assert "sys.argv" in captured + + @pytest.mark.skipif(not HAS_MORE_ITERTOOLS, reason="Unable to load more_itertools") def test_exactly1(self): """Ensure exactly1 works as expected""" debug.trace(4, "test_exactly1()") @@ -172,9 +171,9 @@ def test_string_diff(self): """Ensure string_diff works as expected""" debug.trace(4, "test_string_diff()") - STRING_ONE = 'one\ntwo\nthree\nfour' - STRING_TWO = 'one\ntoo\ntree\nfour' - EXPECTED_DIFF = ( + string_one = 'one\ntwo\nthree\nfour' + string_two = 'one\ntoo\ntree\nfour' + expected_diff = ( ' one\n' '< two\n' '… ^\n' @@ -186,18 +185,69 @@ def test_string_diff(self): ' four\n' ) - assert THE_MODULE.string_diff(STRING_ONE, STRING_TWO) == EXPECTED_DIFF + assert THE_MODULE.string_diff(string_one, string_two) == expected_diff + - @pytest.mark.xfail # TODO: remove xfail def test_elide_string_values(self): """Ensure elide_string_values works as expected""" debug.trace(4, "test_elide_string_values()") - self.do_assert(False, "TODO: code the test") - - def test_misc(self): - """Test miscellaneous stuff""" - debug.trace(4, "test_misc()") - assert("exactly_n" in dir(more_itertools)) + hello = "hello" + assert 'hell...' == THE_MODULE.elide_string_values(hello, max_len=4) + + def test_is_close(self): + """ensure is_close works as expected""" + debug.trace(4, "test_is_close()") + assert THE_MODULE.is_close(1.0 + 0.999 , 2.0, 0.001) + assert not THE_MODULE.is_close(1.0 + 0.999 , 2.0, 0.0001) + + def test_get_date_ddmmmyy(self): + """ensure get_date_ddmmmyy works as expected""" + debug.trace(4, "test_get_date_ddmmmyy()") + assert THE_MODULE.get_date_ddmmmyy(datetime.date(2004, 9, 16)) == '16sep04' + + def test_parse_timestamp(self): + """ensure parse_timestamp works as expected""" + debug.trace(4, "test_parse_timestamp()") + ts = datetime.datetime(2004, 9, 16, 12, 30, 25, 123123) + ts_iso = '2004-09-16T12:30:25.1231234Z' + ts_iso_2 = '2004-09-16T12:30:25.123123Z' + parsed_ts = THE_MODULE.parse_timestamp(ts_iso, truncate=True) + parsed_ts_truncated = THE_MODULE.parse_timestamp(ts_iso_2, truncate=False) + assert parsed_ts == ts + assert parsed_ts_truncated == ts + + def test_add_timestamp_diff(self): + """ensure add_timestamp_diff works as expected""" + debug.trace(4, "test_add_timestamp_diff()") + timestamp = "timestamp 2004-09-16T12:30:25.1231234Z" + file_in = f"{self.temp_file}.in" + file_out = f"{self.temp_file}.out" + system.write_file(file_in, timestamp) + THE_MODULE.add_timestamp_diff(file_in, file_out) + contents = system.read_file(file_out) + assert contents == f"{timestamp} [0]\n" + + def test_random_int(self): + """ensure random_int works as expected""" + debug.trace(4, "test_random_int()") + assert 0 <= THE_MODULE.random_int(0,4) <= 4 + + def test_random_float(self): + """ensure random_float works as expected""" + debug.trace(4, "test_random_float()") + assert 0 <= THE_MODULE.random_float(0,4.3) < 4.3 + + def test_time_function(self): + """ensure time_function works as expected""" + debug.trace(4, "test_time_function()") + ms = THE_MODULE.time_function(time.sleep, 0.25) + assert math.floor(ms) == 250 + + def test_get_class_from_name(self): + """ensure get_class_from_name works as expected""" + debug.trace(4, "test_get_class_from_name()") + result_class = THE_MODULE.get_class_from_name('date', 'datetime') + assert result_class is datetime.date if __name__ == '__main__': debug.trace_current_context() diff --git a/mezcla/tests/test_system.py b/mezcla/tests/test_system.py index cc9f90ab..2cf49cb1 100755 --- a/mezcla/tests/test_system.py +++ b/mezcla/tests/test_system.py @@ -17,13 +17,14 @@ import time import sys import re +import pickle # Installed packages import pytest -import pickle # Local packages from mezcla.unittest_wrapper import TestWrapper +from mezcla.unittest_wrapper import trap_exception from mezcla import glue_helpers as gh from mezcla.my_regex import my_re from mezcla import debug @@ -34,6 +35,7 @@ class TestSystem(TestWrapper): """Class for test case definitions""" + script_module = None def test_maxint(self): """Ensure maxint works as expected""" @@ -174,7 +176,7 @@ def test_get_exception(self): try: raise RuntimeError("testing") except RuntimeError: - exception = THE_MODULE.get_exception() + exception = THE_MODULE.get_exception() assert str(exception[1]) == "testing" def test_print_error(self): @@ -199,17 +201,24 @@ def test_print_exception_info(self): assert "Foobar" in captured @pytest.mark.xfail + @trap_exception # TODO: remove when debugged def test_exit(self): """Ensure exit works as expected""" + # Note: This modifies sys.exit so that system.exit doesn't really exit. debug.trace(4, "test_exit()") - def sys_exit_mock(): - return 'exit' - ## BAD: self.set_attr(sys, "exit", sys_exit_mock) + # + EXIT = 'exit' + def sys_exit_mock(_status=None): + """Stub for sys.exit that just returns 'exit' text""" + debug.trace(4, "sys_exit_mock()") + return EXIT + # self.monkeypatch.setattr(sys, "exit", sys_exit_mock) - assert THE_MODULE.exit('test exit {method}', method='method') == 'exit' + MESSAGE = "test_exit method" + self.do_assert(THE_MODULE.exit(MESSAGE) == EXIT) # Exit is mocked, ignore code editor hidding captured = self.get_stderr() - assert "test exit method" in captured + self.do_assert(MESSAGE in captured) def test_setenv(self): """Ensure setenv works as expected""" @@ -220,26 +229,22 @@ def test_setenv(self): def test_print_full_stack(self): """Ensure print_full_stack works as expected""" debug.trace(4, "test_print_full_stack()") - def raiseException(): - raise RuntimeError('test') try: - raiseException() + raise RuntimeError('test') except RuntimeError: THE_MODULE.print_full_stack(sys.stderr) - capturedError = self.get_stderr() - assert 'RuntimeError' in capturedError + captured_error = self.get_stderr() + assert 'RuntimeError' in captured_error def test_trace_stack(self): """Ensure trace_stack works as expected""" debug.trace(4, "test_trace_stack()") - def raiseException(): - raise RuntimeError('test') try: - raiseException() + raise RuntimeError('test') except RuntimeError: THE_MODULE.trace_stack(1, sys.stderr) - capturedError = self.get_stderr() - assert 'RuntimeError' in capturedError + captured_error = self.get_stderr() + assert 'RuntimeError' in captured_error def test_get_current_function_name(self): """Ensure get_current_function_name works as expected""" @@ -267,8 +272,8 @@ def test_save_object(self): THE_MODULE.save_object(test_filename, test_dict) - test_file = open(test_filename, 'rb') - actual_object = pickle.load(test_file) + with open(test_filename, 'rb') as test_file: + actual_object = pickle.load(test_file) assert actual_object == test_dict test_file.close() @@ -282,9 +287,9 @@ def test_load_object(self): 2: 'second', } test_filename = gh.get_temp_file() - test_file = open(test_filename, 'wb') - pickle.dump(test_dict, test_file) - test_file.close() + with open(test_filename, 'wb') as test_file : + pickle.dump(test_dict, test_file) + test_file.close() assert THE_MODULE.load_object(test_filename) == test_dict # Test invalid file @@ -393,7 +398,7 @@ def test_read_directory(self): split = gh.create_temp_file('').split('/') path = '/'.join(split[:-1]) filename = split[-1] - assert filename in THE_MODULE.read_directory(path) + assert filename in THE_MODULE.read_directory(path) def test_get_directory_filenames(self): """Ensure get_directory_filenames works as expected""" @@ -522,7 +527,6 @@ def test_write_binary_file(self): THE_MODULE.write_binary_file(filename, bytes("binary", "UTF-8")) assert THE_MODULE.read_binary_file(filename) == b'binary' - def test_write_lines(self): """Ensure write_lines works as expected""" debug.trace(4, "test_write_lines()") @@ -565,13 +569,13 @@ def test_get_file_modification_time(self): timestamp1 = THE_MODULE.get_file_modification_time(filedir1)[:19] timestamp2 = THE_MODULE.get_file_modification_time(filedir2)[:19] # get and format local time - timestampNow = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) + now = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) - # test timestamps are equal + # test timestamps are equal assert timestamp1 == timestamp2 # test timestamp is equal to actual time (ignoring miliseconds) - assert timestamp1 == timestampNow + assert timestamp1 == now def test_remove_extension(self): """Ensure remove_extension works as expected""" @@ -604,7 +608,7 @@ def test_get_file_size(self): def test_form_path(self): """Ensure form_path works as expected""" debug.trace(4, "test_form_path()") - assert THE_MODULE.form_path('/usr', 'bin', 'cat') == '/usr/bin/cat' + assert THE_MODULE.form_path('/usr', 'bin', 'cat') == '/usr/bin/cat' def test_is_directory(self): """Ensure is_directory works as expected""" @@ -629,7 +633,8 @@ def test_create_directory(self): def test_get_current_directory(self): """Ensure get_current_directory works as expected""" debug.trace(4, "test_get_current_directory()") - assert '/home/' in THE_MODULE.get_current_directory() + ## BAD: assert '/home/' in THE_MODULE.get_current_directory() + assert 'mezcla' in THE_MODULE.get_current_directory() def test_set_current_directory(self): """Ensure set_current_directory works as expected""" @@ -658,7 +663,7 @@ def test_from_utf8(self): assert THE_MODULE.from_utf8("\xBF") == "\u00BF" # assert THE_MODULE.to_unicode("\xEF\xBB\xBF") == "\ufeff" # Lorenzo: can't convert "\ufeff" to BOM, but can convert "\xEF\xBB\xBF" - + def test_to_unicode(self): """Ensure to_unicode works as expected""" debug.trace(4, "test_to_unicode()") @@ -718,7 +723,6 @@ def test_real_path(self): debug.trace(4, "test_real_path()") assert THE_MODULE.real_path("/etc/mtab").startswith("/proc") - @pytest.mark.xfail def test_get_module_version(self): """Ensure get_module_version works as expected""" debug.trace(4, "test_get_module_version()") @@ -734,7 +738,7 @@ def test_get_module_version(self): debug.trace(4, f"Ignoring pip freeze line: {line}") percent = (num_good / num_total * 100) if num_total else 0 debug.trace_expr(5, num_good, num_total, percent) - assert (percent >= 90) + assert percent >= 90 def test_intersection(self): """Ensure intersection works as expected""" diff --git a/mezcla/tests/test_tpo_common.py b/mezcla/tests/test_tpo_common.py index 017ded12..5d7459a6 100755 --- a/mezcla/tests/test_tpo_common.py +++ b/mezcla/tests/test_tpo_common.py @@ -7,6 +7,11 @@ # - This can be run as follows: # $ PYTHONPATH=".:$PYTHONPATH" python ./mezcla/tests/test_tpo_common.py # +# Warning: +# - *** The tpo_common.py module is being phased out. Although there are +# a bunch of "work-in-progress" tests below, they are low priority because +# most are addressed by test_system.py or test_debug.py. +# # TODO: # - Address commonly used debugging functions (e.g., debug_print) by redirecting output (via remapping sys.stderr to a file) and then checking file contents. # - add tests for normalize_unicode, ensure_unicode and other problematic functions @@ -20,10 +25,12 @@ # Standard modules import sys +import re # Installed modules import pytest import pickle +import trace # Local modules from mezcla import debug @@ -60,7 +67,16 @@ def test_debugging_level(self): def test_debug_trace_without_newline(self): """Ensure debug_trace_without_newline works as expected""" debug.trace(4, "test_debug_trace_without_newline()") - ## TODO: WORK-IN-PROGRESS + tracer = trace.Trace(countfuncs=1) + tracer.runfunc(THE_MODULE.debug_trace_without_newline, ('test debug trace withouht newline')) + + # redirect write_results to temp file + temp = self.get_temp_file() + tracer.results().write_results(coverdir=temp) + + captured = self.get_stdout() + assert re.search(r'modulename: debug, funcname: trace', captured) + def test_debug_trace(self): """Ensure debug_trace works as expected""" @@ -80,22 +96,61 @@ def test_debug_format(self): def test_debug_timestamp(self): """Ensure debug_timestamp works as expected""" debug.trace(4, "test_debug_timestamp()") - ## TODO: WORK-IN-PROGRESS + tracer = trace.Trace(countfuncs=1) + tracer.runfunc(THE_MODULE.debug_timestamp) + + # redirect write_results to temp file + temp = self.get_temp_file() + tracer.results().write_results(coverdir=temp) + + captured = self.get_stdout() + assert re.search(r'modulename: debug, funcname: timestamp', captured) + @trap_exception def test_debug_raise(self): """Ensure debug_raise works as expected""" debug.trace(4, "test_debug_raise()") - ## TODO: WORK-IN-PROGRESS + tracer = trace.Trace(countfuncs=1) + try: + raise RuntimeError + except RuntimeError: + with pytest.raises(RuntimeError): + tracer.runfunc(THE_MODULE.debug_raise) + + # redirect write_results to temp file + temp = self.get_temp_file() + tracer.results().write_results(coverdir=temp) + + captured = self.get_stdout() + assert re.search(r'modulename: debug, funcname: raise_exception', captured) + def test_trace_array(self): """Ensure trace_array works as expected""" debug.trace(4, "test_trace_array()") - ## TODO: WORK-IN-PROGRESS + tracer = trace.Trace(countfuncs=1) + tracer.runfunc(THE_MODULE.trace_array, (['test', 'trace', 'array'])) + + # redirect write_results to temp file + temp = self.get_temp_file() + tracer.results().write_results(coverdir=temp) + + captured = self.get_stdout() + assert re.search(r'modulename: debug, funcname: trace_values', captured) def test_trace_object(self): """Ensure trace_object works as expected""" debug.trace(4, "test_trace_object()") - ## TODO: WORK-IN-PROGRESS + tracer = trace.Trace(countfuncs=1) + tracer.runfunc(THE_MODULE.trace_object, ('test_trace_object'), show_methods_etc=True) + + # redirect write_results to temp file + temp = self.get_temp_file() + tracer.results().write_results(coverdir=temp) + + captured = self.get_stdout() + assert re.search(r'modulename: debug, funcname: trace_object', captured) + def test_trace_value(self): """Ensure trace_value works as expected""" @@ -105,27 +160,49 @@ def test_trace_value(self): def test_trace_current_context(self): """Ensure trace_current_context works as expected""" debug.trace(4, "test_trace_current_context()") - ## TODO: WORK-IN-PROGRESS + tracer = trace.Trace(countfuncs=1) + tracer.runfunc(THE_MODULE.trace_current_context, show_methods_etc=True) + + # redirect write_results to temp file + temp = self.get_temp_file() + tracer.results().write_results(coverdir=temp) + + captured = self.get_stdout() + assert re.search(r'modulename: debug, funcname: trace_current_context', captured) def test_during_debugging(self): """Ensure during_debugging works as expected""" debug.trace(4, "test_during_debugging()") + ## TODO: WORK-IN-PROGRESS def test_debugging(self): """Ensure debugging works as expected""" debug.trace(4, "test_debugging()") - ## TODO: WORK-IN-PROGRESS + THE_MODULE.set_debug_level(4) + assert THE_MODULE.debugging(2) + assert THE_MODULE.debugging(4) + assert not THE_MODULE.debugging(6) def test_detailed_debugging(self): """Ensure detailed_debugging works as expected""" debug.trace(4, "test_detailed_debugging()") - ## TODO: WORK-IN-PROGRESS + THE_MODULE.set_debug_level(2) + assert not THE_MODULE.detailed_debugging() + THE_MODULE.set_debug_level(4) + assert THE_MODULE.detailed_debugging() + THE_MODULE.set_debug_level(6) + assert THE_MODULE.detailed_debugging() def test_verbose_debugging(self): """Ensure verbose_debugging works as expected""" debug.trace(4, "test_verbose_debugging()") - ## TODO: WORK-IN-PROGRESS + THE_MODULE.set_debug_level(2) + assert not THE_MODULE.verbose_debugging() + THE_MODULE.set_debug_level(5) + assert THE_MODULE.verbose_debugging() + THE_MODULE.set_debug_level(7) + assert THE_MODULE.verbose_debugging() def test_to_string(self): """Ensure to_string works as expected""" @@ -294,7 +371,7 @@ def test_load_object(self): 1: 'first', 2: 'second', } - test_filename = gh.get_temp_file() + test_filename = self.get_temp_file() test_file = open(test_filename, 'wb') pickle.dump(test_dict, test_file) test_file.close() @@ -308,7 +385,7 @@ def test_store_object(self): 1: 'first', 2: 'second', } - test_filename = gh.get_temp_file() + test_filename = self.get_temp_file() THE_MODULE.store_object(test_filename, test_dict) @@ -327,7 +404,7 @@ def test_dump_stored_object(self): 1: 'first', 2: 'second', } - test_filename = gh.get_temp_file() + test_filename = self.get_temp_file() THE_MODULE.store_object(test_filename, test_dict) @@ -366,7 +443,7 @@ def test_create_boolean_lookup_table(self): 'isbusiness - true': True, } - temp_file = gh.get_temp_file() + temp_file = self.get_temp_file() gh.write_file(temp_file, content) assert THE_MODULE.create_boolean_lookup_table(temp_file) == expected @@ -507,77 +584,71 @@ def test_memodict(self): debug.trace(4, "test_memodict()") ## TODO: WORK-IN-PROGRESS - -class TestTpoCommon2: - """Another class for testcase definition - Note: works around silly issues with pytest and TestWrapper (e.g., capsys and monkeypatch) - """ - @pytest.mark.xfail # TODO: remove xfail - def test_exit(self, monkeypatch, capsys): + def test_exit(self): """Ensure exit works as expected""" debug.trace(4, "test_exit()") def sys_exit_mock(): return 'exit' - monkeypatch.setattr(sys, "exit", sys_exit_mock) + self.monkeypatch.setattr(sys, "exit", sys_exit_mock) assert THE_MODULE.exit('test exit method') == 'exit' # Exit is mocked, ignore code editor hiding ## TODO: for some reason (probably the debug level) the message is not being printed - captured = capsys.readouterr() + captured = self.get_stdout_stderr() debug.trace_object(5, captured) ## TODO: assert "test exit method" in captured.err - debug.assertion("test exit method" in captured.err) + debug.assertion("test exit method" in captured[1]) - def test_dummy_main(self, capsys): + def test_dummy_main(self): """Ensure dummy_main works as expected""" debug.trace(4, "test_dummy_main()") THE_MODULE.dummy_main() - captured = capsys.readouterr() - assert 'Environment options' in captured.out + captured = self.get_stdout() + assert 'Environment options' in captured - @pytest.mark.xfail # TODO: remove xfail + # @pytest.mark.xfail # TODO: remove xfail @trap_exception - def test_getenv(self, monkeypatch): + def test_getenv(self): """Ensure getenv works as expected""" debug.trace(4, "test_getenv()") - monkeypatch.setenv('TEST_ENV_VAR', 'some value', prepend=False) + self.monkeypatch.setenv('TEST_ENV_VAR', 'some value', prepend=False) assert THE_MODULE.getenv('TEST_ENV_VAR') == 'some value' - def test_getenv_value(self, monkeypatch): + def test_getenv_value(self): """Ensure getenv_value works as expected""" debug.trace(4, "test_getenv_value()") - monkeypatch.setenv('NEW_ENV_VAR', 'some value', prepend=False) + self.monkeypatch.setenv('NEW_ENV_VAR', 'some value', prepend=False) assert THE_MODULE.getenv_value('NEW_ENV_VAR', default='empty', description='another test env var') == 'some value' assert THE_MODULE.env_defaults['NEW_ENV_VAR'] == 'empty' assert THE_MODULE.env_options['NEW_ENV_VAR'] == 'another test env var' - def test_getenv_text(self, monkeypatch): + def test_getenv_text(self): """Ensure getenv_text works as expected""" debug.trace(4, "test_getenv_text()") - monkeypatch.setenv('TEST_ENV_VAR', 'some value', prepend=False) + self.monkeypatch.setenv('TEST_ENV_VAR', 'some value', prepend=False) assert THE_MODULE.getenv_text('TEST_ENV_VAR') == 'some value' assert THE_MODULE.getenv_text("REALLY FUBAR?", False) == 'False' - def test_getenv_number(self, monkeypatch): + def test_getenv_number(self): """Ensure getenv_number works as expected""" debug.trace(4, "test_getenv_number()") - monkeypatch.setenv('TEST_NUMBER', '9.81', prepend=False) + self.monkeypatch.setenv('TEST_NUMBER', '9.81', prepend=False) assert THE_MODULE.getenv_number('TEST_NUMBER', default=20) == 9.81 assert THE_MODULE.getenv_number("REALLY FUBAR", 123) == 123.0 - def test_getenv_int(self, monkeypatch): + def test_getenv_int(self): """Ensure getenv_int works as expected""" debug.trace(4, "test_getenv_int()") - monkeypatch.setenv('TEST_NUMBER', '34', prepend=False) + self.monkeypatch.setenv('TEST_NUMBER', '34', prepend=False) assert THE_MODULE.getenv_int('TEST_NUMBER', default=20) == 34 assert THE_MODULE.getenv_int("REALLY FUBAR", 123) == 123 - def test_getenv_bool(self, monkeypatch): + def test_getenv_bool(self): """Ensure getenv_bool works as expected""" debug.trace(4, "test_getenv_bool()") - monkeypatch.setenv('TEST_BOOL', 'FALSE', prepend=False) + self.monkeypatch.setenv('TEST_BOOL', 'FALSE', prepend=False) assert not THE_MODULE.getenv_bool('TEST_BOOL', None) - monkeypatch.setenv('TEST_BOOL', ' true ', prepend=False) + self.monkeypatch.setenv('TEST_BOOL', ' true ', prepend=False) assert THE_MODULE.getenv_bool('TEST_BOOL', None) assert not isinstance(THE_MODULE.getenv_boolean("REALLY FUBAR?", None), bool) assert isinstance(THE_MODULE.getenv_boolean("REALLY FUBAR?", False), bool)