From 6b80e0dab29c85a73310a9107de11744384eb648 Mon Sep 17 00:00:00 2001 From: Thomas Wemyss Date: Thu, 5 Nov 2020 12:15:03 +0000 Subject: [PATCH] Start moving over to loading tests from yaml file. Answers UCL-RITS/rse-classwork-2020#92 --- requirements.txt | 3 +- week05-testing/fixture.yaml | 42 +++++++++++++++ week05-testing/test_times.py | 4 +- week05-testing/test_times_parameterised.py | 60 +++++++++++++--------- week05-testing/times.py | 17 ++++-- 5 files changed, 95 insertions(+), 31 deletions(-) create mode 100644 week05-testing/fixture.yaml diff --git a/requirements.txt b/requirements.txt index a10c118..e6aadb1 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,5 @@ pytest pytest-cov datetime -codecov \ No newline at end of file +codecov +pyyaml \ No newline at end of file diff --git a/week05-testing/fixture.yaml b/week05-testing/fixture.yaml new file mode 100644 index 0000000..25d46c7 --- /dev/null +++ b/week05-testing/fixture.yaml @@ -0,0 +1,42 @@ +- generic: + time_range_1: + start: 2010-01-12 10:00:00 + end: 2010-01-12 12:00:00 + time_range_2: + start: 2010-01-12 10:30:00 + end: 2010-01-12 10:45:00 + num_intervals: 2 + time_between_intervals: 60 + expected: + - ["2010-01-12 10:30:00", "2010-01-12 10:37:00"] + - ["2010-01-12 10:38:00", "2010-01-12 10:45:00"] +- no_overlap: + time_range_1: + start: 2010-01-12 10:00:00 + end: 2010-01-12 12:00:00 + time_range_2: + start: 2010-01-12 12:30:00 + end: 2010-01-12 12:45:00 + expected: [] +- several_overlaps: + time_range_1: + start: 2010-01-12 10:00:00 + end: 2010-01-12 12:00:00 + num_intervals: 2 + time_between_intervals: 0 + time_range_2: + start: 2010-01-12 10:30:00 + end: 2010-01-12 11:30:00 + num_intervals: 2 + time_between_intervals: 0 + expected: + - ["2010-01-12 10:30:00", "2010-01-12 11:00:00"] + - ["2010-01-12 11:00:00", "2010-01-12 11:30:00"] +- one_finish_another_start: + time_range_1: + start: 2010-01-12 10:00:00 + end: 2010-01-12 12:00:00 + time_range_2: + start: 2010-01-12 12:00:00 + end: 2010-01-12 12:30:00 + expected: [] \ No newline at end of file diff --git a/week05-testing/test_times.py b/week05-testing/test_times.py index aba3b86..0aafa02 100644 --- a/week05-testing/test_times.py +++ b/week05-testing/test_times.py @@ -37,7 +37,5 @@ def test_touching_times(self): def test_negative_time_interval(self): """Tests a time range which goes backwards""" - t1 = times.time_range("2010-01-12 10:00:00", "2010-01-12 12:00:00") - t2 = times.time_range("2010-01-12 11:00:00", "2010-01-12 10:30:00") with pytest.raises(ValueError): - times.compute_overlap_time(t1, t2) + times.time_range("2010-01-12 15:00:00", "2010-01-12 12:00:00") diff --git a/week05-testing/test_times_parameterised.py b/week05-testing/test_times_parameterised.py index ca2f887..9e75cb0 100644 --- a/week05-testing/test_times_parameterised.py +++ b/week05-testing/test_times_parameterised.py @@ -1,28 +1,42 @@ import times import pytest +import yaml -class TestTimeOverlap: - """TestTimeOverlap class contains all functions involved in - testing the overlap of two times based on example UCL RITS code""" - @pytest.mark.parametrize("time_range_1, time_range_2, expected", [ - # Test hardcoded input from example problem - (times.large, times.short, [('2010-01-12 10:30:00', '2010-01-12 10:37:00'), ('2010-01-12 10:38:00', '2010-01-12 10:45:00')]), - # Tests two time ranges that do not overlap - (times.time_range("2010-01-12 10:00:00", "2010-01-12 12:00:00"), times.time_range("2010-01-12 12:30:00", "2010-01-12 12:45:00"), []), - # Tests intervals where each has several intervals and two sub-intervals overlap - (times.time_range("2010-01-12 10:00:00", "2010-01-12 12:00:00", 2, 0), times.time_range("2010-01-12 10:30:00", "2010-01-12 11:30:00", 2, 0), [('2010-01-12 10:30:00', '2010-01-12 11:00:00'),('2010-01-12 11:00:00', '2010-01-12 11:30:00')]), - # Tests two intervals where one finishes at exactly the same time another started - (times.time_range("2010-01-12 10:00:00", "2010-01-12 12:00:00"), times.time_range("2010-01-12 12:00:00", "2010-01-12 12:30:00"), []) - ]) - def test_given_input(self, time_range_1, time_range_2, expected): - """Tests hardcoded input given as part of the example problem""" - result = times.compute_overlap_time(time_range_1, time_range_2) - assert result == expected +def get_test_data(file_path): + test_array = [] + # Load the fixtures for testing + with open(file_path) as file: + loaded_tests = yaml.load(file, Loader=yaml.SafeLoader) + for test in loaded_tests: + # Get test parameters + test_parameters = list(test.values())[0] + # Convert expected arrays into tuples + expected_values = [] + for expected in test_parameters['expected']: + expected_values.append((expected[0], expected[1])) + # Make the current test tuple + current_test = (times.time_range( + test_parameters['time_range_1']['start'], + test_parameters['time_range_1']['end'], + test_parameters['time_range_1'].get('num_intervals', 1), + test_parameters['time_range_1'].get('time_between_intervals', 0)), + times.time_range( + test_parameters['time_range_2']['start'], + test_parameters['time_range_2']['end'], + test_parameters['time_range_2'].get('num_intervals', 1), + test_parameters['time_range_2'].get('time_between_intervals', 0)), + expected_values) + # Add it to the array + test_array.append(current_test) + return test_array - def test_negative_time_interval(self): - """Tests a time range which goes backwards""" - t1 = times.time_range("2010-01-12 10:00:00", "2010-01-12 12:00:00") - t2 = times.time_range("2010-01-12 11:00:00", "2010-01-12 10:30:00") - with pytest.raises(ValueError): - times.compute_overlap_time(t1, t2) +@pytest.mark.parametrize("time_range_1, time_range_2, expected", get_test_data("./week05-testing/fixture.yaml")) +def test_fixture_input(time_range_1, time_range_2, expected): + result = times.compute_overlap_time(time_range_1, time_range_2) + assert result == expected + +def test_negative_time_interval(): + """Tests a time range which goes backwards""" + with pytest.raises(ValueError): + times.time_range("2010-01-12 15:00:00", "2010-01-12 12:00:00") diff --git a/week05-testing/times.py b/week05-testing/times.py index 4ad010a..ab79dfc 100644 --- a/week05-testing/times.py +++ b/week05-testing/times.py @@ -2,8 +2,19 @@ def time_range(start_time, end_time, number_of_intervals=1, gap_between_intervals_s=0): - start_time_s = datetime.datetime.strptime(start_time, "%Y-%m-%d %H:%M:%S") - end_time_s = datetime.datetime.strptime(end_time, "%Y-%m-%d %H:%M:%S") + # Parse datetimes if not already parsed + if isinstance(start_time, datetime.datetime): + start_time_s = start_time + else: + start_time_s = datetime.datetime.strptime(start_time, "%Y-%m-%d %H:%M:%S") + if isinstance(end_time, datetime.datetime): + end_time_s = end_time + else: + end_time_s = datetime.datetime.strptime(end_time, "%Y-%m-%d %H:%M:%S") + + if start_time_s > end_time_s: + raise ValueError("Start time cannot be bigger than end time") + d = (end_time_s - start_time_s).total_seconds() / number_of_intervals + gap_between_intervals_s * (1 / number_of_intervals - 1) sec_range = [(start_time_s + datetime.timedelta(seconds=i * d + i * gap_between_intervals_s), start_time_s + datetime.timedelta(seconds=(i + 1) * d + i * gap_between_intervals_s)) @@ -15,8 +26,6 @@ def compute_overlap_time(range1, range2): overlap_time = [] for start1, end1 in range1: for start2, end2 in range2: - if start1 > end1 or start2 > end2: - raise ValueError("Start time cannot be bigger than end time") low = max(start1, start2) high = min(end1, end2) if low != high and low < high: