When it comes to testing, we usually hear that the tests are too slow. While that is a problem, we can also run into unexpected problems if the tests run too fast.
We had this line in one of our tests that checks with Fluent Assertions that the newest entry for our order history was written in the last minute:
1 |
newestEntry.Timestamp.Should().BeWithin(1.Minutes()).Before(DateTime.Now); |
That test worked for many months without a problem. Before that we checked for a 2 second difference but that was often not enough.
But after an update to the virtualisation software our box runs on, we got this error:
Expected the date and time
<2024-05-27 06:34:27.160> to be within 1m before
<2024-05-27 06:34:27.1599226>, but it is ahead by 77.4µs.
The µs stands for microsecond, what is one millionth of a second. It looks as if our entry somehow calls from the future – but it is not. The reason for this time-travel is that SQL Server truncates timestamps at 3 decimal places of a second, while DateTime.now
gives us 7 decimal places.
Since the test now runs so fast, the truncate part of the decimal places starts to matter. As a quick fix for this problem, we add a second to the DateTime.now
call to compensate for the rounding in SQL Server:
1 |
newestEntry.Timestamp.Should().BeWithin(1.Minutes()).Before(DateTime.Now.AddSeconds(1)); |
This additional second was all it took to stop the flakiness of this test. Nonetheless, we keep an eye on this test to reduce the 1.Minutes()
to a shorter time span.