From 92481234bb1008457cf1cb4513fc3012b9f03be6 Mon Sep 17 00:00:00 2001 From: Joanna Date: Sun, 20 Dec 2020 20:14:12 +0100 Subject: [PATCH] Performing test on times with data in a fixture Answers UCL Issue #92 --- week05-testing/fixture.yaml | 21 +++++++++++ week05-testing/test_times_fixtures.py | 42 +++++++++++++++++++++ week05-testing/times_fixtures.py | 54 +++++++++++++++++++++++++++ 3 files changed, 117 insertions(+) create mode 100644 week05-testing/fixture.yaml create mode 100644 week05-testing/test_times_fixtures.py create mode 100644 week05-testing/times_fixtures.py diff --git a/week05-testing/fixture.yaml b/week05-testing/fixture.yaml new file mode 100644 index 0000000..a3b9003 --- /dev/null +++ b/week05-testing/fixture.yaml @@ -0,0 +1,21 @@ +- generic: + time_range_1: ["2010-01-12 10:00:00", "2010-01-12 12:00:00"] + time_range_2: ["2010-01-12 10:30:00", "2010-01-12 10:45:00", 2, 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: ["2010-01-12 10:00:00", "2010-01-12 11:00:00"] + time_range_2: ["2010-01-12 12:30:00", "2010-01-12 12:45:00", 2, 60] + expected: [] +- multiple_overlaps: + time_range_1: ["2010-01-12 10:00:00", "2010-01-12 13:00:00", 3, 900] + time_range_2: ["2010-01-12 10:40:00", "2010-01-12 11:20:00", 2, 120] + expected: + - ["2010-01-12 10:40:00","2010-01-12 10:50:00"] + - ["2010-01-12 11:05:00", "2010-01-12 11:20:00"] +- touching: + time_range_1: ["2010-01-12 10:00:00", "2010-01-12 11:00:00"] + time_range_2: ["2010-01-12 11:00:00", "2010-01-12 12:45:00"] + expected: [] + diff --git a/week05-testing/test_times_fixtures.py b/week05-testing/test_times_fixtures.py new file mode 100644 index 0000000..a56ff09 --- /dev/null +++ b/week05-testing/test_times_fixtures.py @@ -0,0 +1,42 @@ +"""The file to test times.py""" + +#import functions from times.py +import pytest +import yaml +from times import compute_overlap_time, time_range + +# get fixture data from yaml file +with open("fixture.yaml", 'r') as yamlfile: + fixture = yaml.safe_load(yamlfile) + print(fixture) + # gives a list of dictionaries for each test case + +# parametrization of entries +@pytest.mark.parametrize("test_name", fixture) +# fixture is a list of dictionaries [{'generic':...}, {'no_overlap':...}, ...] + +def test_parametrized_overlap(test_name): + # test_name will be a dictionary, e.g. for the first case: {'generic': {'time_range_1':..., 'time_range2':..., 'expected':...}} + properties = list(test_name.values())[0] + first_range = time_range(*properties['time_range_1']) + second_range = time_range(*properties['time_range_2']) + + expected = [(start, stop) for start, stop in properties['expected']] + result = compute_overlap_time(first_range, second_range) + assert result == expected + +#negative test for a date going backwards +#check that the error message matches with the one raised in time_range function of times.py + +# first possible solution +def test_negative_time_range(): + with pytest.raises(ValueError) as e: + time_range("2010-01-12 10:00:00", "2010-01-12 09:30:00") + # lines after the error is raised are not executed in the pytest.raises context, so the assertion has to be outside the "with" + assert e.match('The end of the time range has to come strictly after its start.') + +# an alternative solution for using pytest.raises to check that the error message is as expected +def test_negative_time_range_alternative(): + expected_error_message = 'The end of the time range has to come strictly after its start.' + with pytest.raises(ValueError, match=expected_error_message): + time_range("2010-01-12 10:00:00", "2010-01-12 09:30:00") \ No newline at end of file diff --git a/week05-testing/times_fixtures.py b/week05-testing/times_fixtures.py new file mode 100644 index 0000000..95e17c5 --- /dev/null +++ b/week05-testing/times_fixtures.py @@ -0,0 +1,54 @@ +"""Exercise #61 - Code""" + +import datetime + +#function to convert the time range into strings of start ta and end tb +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") + + if(start_time_s>=end_time_s): + raise ValueError('The end of the time range has to come strictly after its start.') + + 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)) + for i in range(number_of_intervals)] + return [(ta.strftime("%Y-%m-%d %H:%M:%S"), tb.strftime("%Y-%m-%d %H:%M:%S")) for ta, tb in sec_range] + + +#function to compute the overlap time +def compute_overlap_time(range1, range2): + overlap_time = [] + for start1, end1 in range1: + for start2, end2 in range2: + + # both ranges need to start before the other ends, otherwise there is no overlap! + if start1<= end2 and start2 <= end1: + low = max(start1, start2) + high = min(end1, end2) + + # in case they touch exactly (end of one is start of the other) --> no overlap + if high == low: + continue # jumps to the next iteration of the loop + + overlap_time.append((low, high)) + + #note: when there is no overlap, overlap_time = [] stays + return overlap_time + + +# this only runs if this module is run directly, if it is imported somewhere then __name__ == times instead!! +if __name__ == "__main__": + #converts the time ranges into strings + large = time_range("2010-01-12 10:00:00", "2010-01-12 12:00:00") + short = time_range("2010-01-12 10:30:00", "2010-01-12 10:45:00", 2, 60) + print(f"large: {large}") + #[('2010-01-12 10:00:00', '2010-01-12 12:00:00')] + print(f"short: {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')] + + # the outputted resulting overlap time + overlap_t = compute_overlap_time(large, short) + print(f"The resulting overlaps are {overlap_t}.") + #[('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 newline at end of file