Reputation: 14185
I have a method to calculate the number of ms between two times.
def time_diff(orig_time):
return int((time.time() - orig_time) * 1000)
It is used similar to:
orig = time.time()
# do stuff
time_duration = time_diff(orig)
I understand this is not necessarily ideal from a repeatability perspective, because time.time()
has some accuracy issues.
From a practical perspective, this function works good enough. I don't need exact precision here and know I lose precision.
However, my issue is when I go to test services relying on this functionality.
It seems I have a few options:
class ReportingTest(TestCase):
def test_time_diff_badly(self):
# this approach is bad and I should not even consider it
orig = time.time()
self.assertEqual(
time_diff(orig),
0)
@patch('time.time')
def test_time_diff_mocked(self, time_mock):
time_mock.return_value = 0
self.assertEqual(
time_diff(0.0015),
1.5)
def test_time_diff_threshold(self):
orig = time.time()
dt = time_diff(orig)
self.assertLessEqual(dt, 0.10)
self.assertGreaterEqual(dt, 0)
The first is clearly bad. There is no value I can put which will consistently return. Mocking seems workable as does the threshold based approach. I don't really like mocking though since it seems a bit pointless to even write the test if I do that.
Is there a better way to test this function?
Upvotes: 0
Views: 37
Reputation: 532418
A unit test doesn't exist to find bugs; it exists to catch bugs introduced at a later date. Don't worry if your test seems trivial.
Here are a few ways to improve your current test:
Don't assume that time.time()
is called. It's currently an implementation detail that your test relies on, so take steps to ensure
that your tests fail if that changes.
time_mock.assert_called()
Depending on what was mocked, you may want to verify the number of times it is called, or what arguments it is called with, but the idea is to try to make your test fail when its underlying assumptions change.
Write multiple tests with different return values. Especially in this case, time.time()
is never going to return the same value twice, so try to anticipate what classes of values it might return that could cause problems. For instance, you assume that time.time()
will return a value greater than orig_time
, but it might not.
Upvotes: 2