1

My team and I are trying to set up some integration tests of a distributed system that is highly dependant on the flow of time and events coming from external sources. Just to give you an idea about what we're working on:

when event A is received within 8:00 AM and 9:00 AM, and afterward, within 5 minutes, a second event B is received, then write a record into the DB with the timestamp at which event A has been received.

Now... writing an integration test against the real system seems complex.

How to set the date of the system under test ?

The system under test should ideally work with a time defined by the integration tests. Maybe the integration test should set the server time at "9:00" when the test starts ? Any other advice ?

How to send events at a known rate ?

Events should be sent with a reproducible and known rhythm, i.e. fire event A at 9:05 and event B at 9:06. Maybe a plain programmable scheduler can be used here ?

How to cope with tests requiring large timeouts ?

Some test scenarios requires that large amount of time pass between two events. Is it possible to artificially speed up the flow of time to compress one hour in just some second in the test ? I though about speeding up the clock of the system (not in the meaning of overclocking, just in the mean of having the seconds ticks faster). It seems to me that this cannot be done in an actual piece of hardware but maybe in a virtual machine this is possible. Any advice on this topic ?

Constraints

  • Not all module being part of the integration tests are under our direct control.
  • 3
    I would suggest that you extract all the calls to "Get current time" into an Interface (or your languages equivalent), so you can inject a different time for each of your tests, and during normal use, it would of course always return the actual time of day. However this will only work for the modules you are directly in control of – Falgantil Jan 17 '18 at 15:29
  • For faking a clock, with the new java time that no longer is a problem. But then the test database has time functions too, – Joop Eggen Jan 17 '18 at 15:38
  • What @Joop said is the real problem, IMHO. – danidemi Jan 17 '18 at 15:57
  • What kind of tests exactly are you trying to write? If you're doing integration tests, you're actually testing the integration of your own code, and external dependencies which you do not control will be mocked because you assume they are already well-tested and working. If you're doing system tests, then you want to test the actual system, i.e. no mocking, and as your tests mimic the actual behaviour, they will be slow. It shouldn't matter too much however, because you have unit and integration tests which can run often and validate the behaviour of your system. – Vincent Savard Jan 17 '18 at 17:36
  • Hi @vincent. Replacing external dependencies with mock can be sometimes a pain. Infact, think you want to mock an external service that feeds your system. How can be sure that your mocked driver generates the same events with the same logical sequence ? Fowler advice to use contract tests but it seems complex to contract test a feeding service. – danidemi Jan 19 '18 at 17:53
6

Never manipulate the actual time time or speed of the system you are testing on just to test time logic. It's hard to get right and may have lots of unforeseen side effects.

Instead, decouple all time-related functionality in your code base; business code will use a trivial implementation that just delegates to the normal functions, and during tests you can mock the time and easily simulate whatever sequence of events you want.

  • Hi @Kilian thx for the answer. What you proposed is what we did in the unit tests. Sadly, in the integration tests there are systems we don't have the control of the sources for, hence we cannot apply what you proposed to them. Any further idea ? – danidemi Jan 17 '18 at 15:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.