I have this class implemented in python on which i am performing some unitests
from datetime import datetime, timedelta
class FreeTime:
"""Range in a timeframe where a task can be located"""
def __init__(self, start: datetime, end: datetime) -> None:
self.start = start
""" start of the freetime """
self.end = end
""" end of the freetime """
self.duration = end - start
""" duration of the freetime"""
def set_start(self, start: datetime):
self.start = start
self.duration = self.end - self.start
def set_duration(self, duration: timedelta):
self.duration = duration
self.start = self.end - self.duration
def __repr__(self) -> str:
return f"FreeTime - {self.start} -> {self.end} - {self.duration}"
The test looks like this:
from datetime import datetime, timedelta
def test_FreeTime():
"""test the FreeTime class"""
start = datetime.now()
end = start timedelta(hours=4.0)
free_time = FreeTime(start=start, end=end)
assert free_time.start == start
assert free_time.end == end
assert free_time.duration == end - start
start_2 = datetime.now() timedelta(hours=1.0)
free_time.set_start(start_2)
assert free_time.start == start_2
assert free_time.duration == end - start_2
delta = timedelta(hours=3.0)
free_time.set_duration(delta)
assert free_time.duration == timedelta(hours=3.0)
assert free_time.start == end - delta
assert str(free_time) == f"FreeTime - {start_2} -> {end} - {delta}"
Strangely when I run the test I get some variant of this assertion error, (some variant meaning the millisecond difference):
assert str(free_time) == f"FreeTime - {start_2} -> {end} - {delta}"
E AssertionError: assert 'FreeTime - 2...544 - 3:00:00' == 'FreeTime - 2...544 - 3:00:00'
E - FreeTime - 2023-01-04 21:54:27.421567 -> 2023-01-05 00:54:27.421544 - 3:00:00
E ? ^^
E FreeTime - 2023-01-04 21:54:27.421544 -> 2023-01-05 00:54:27.421544 - 3:00:00
E ? ^^
However I dont get how or where the difference in millisecond comes from, since all previous assertion tests pass wiht out errors. It alwasy failes on this assertion but the offset is different every time.
I allready tried instantiatiating all timedelata objects whith floats instead of int, but this did not have any effect.
CodePudding user response:
I try to untangle your test logic:
start = t1 = now()
end = t1 4h
free_time.start = start = t1
free_time.end = end = t1 4h
start2 = t2 = now() 1h = t1 delta_t 1h
free_time.start = start2 = t2 = t1 delta_t 1h
free_time.duration = end - start2 = t1 4h - t2
free_time.duration = 3h
free_time.start = free_time.end - 3h = end - 3h = t1 1h
The end result is:
free_time.start = t1 1h
free_time.end = t1 4h
free_time.duration = 3h
And your assertion is that
free_time.start == start2 == t2 == t1 delta_t 1h
free_time.end == end == t1 4h
free_time.duration == 3h
The error in your logic is that you assume the two calls to datetime.now()
result in the same value. They do not. Python is not infinitely fast and the timestamp resolution is sufficiently small that both result in different values, thus resulting in the time difference which I put in the equations as delta_t
CodePudding user response:
Yes - Based on @homer512 's input, change your test class to be
from datetime import datetime, timedelta
def test_FreeTime():
"""test the FreeTime class"""
start = datetime.now()
end = start timedelta(hours=4.0)
free_time = FreeTime(start=start, end=end)
assert free_time.start == start
assert free_time.end == end
assert free_time.duration == end - start
start_2 = start timedelta(hours=1.0)
free_time.set_start(start_2)
assert free_time.start == start_2
assert free_time.duration == end - start_2
delta = timedelta(hours=3.0)
free_time.set_duration(delta)
assert free_time.duration == timedelta(hours=3.0)
assert free_time.start == end - delta
assert str(free_time) == f"FreeTime - {start_2} -> {end} - {delta}"