4

There are some well-known techniques for dealing with the notion of time in unit tests. These allow you to write unittests that always work with a specific time so the outcome of the test is predictable and can be verified. However, these techniques do not work with integration tests/UI test as the test and the application itself are separated (very much so in web applications where your application under test could be deployed on a separate server).

For example, let's assume we are developing an appointment system that needs to implement a 'suggest the first available appointment date'-button. If the button is clicked, it needs to suggest the first available timeslot for the next business day. This means that if the button is clicked on any given day of the week except friday it should suggest a slot in the next day, BUT on friday and saturday it should suggest a slot on monday.

How would one go about testing this requirement?

(I know it is possible to work around the issue for this specific example but bear with me - there are always situations where the test cannot supply the data to work from. I didn't want to supply an overly complicated example.)

  • Let the client supply the current time? – Patrick Sep 24 '13 at 8:40
  • That works around this issue for the specific example but is not always possible... – JDT Sep 24 '13 at 8:47
  • 6
    for many things that require outside persistent state in tests it is common to mock the interface to it so it always returns a predictable value, you could do the same for the system time... – ratchet freak Sep 24 '13 at 8:50
  • @ratchetfreak has it exactly right. Why would you expose your tests to potential errors/discrepancies in system time on the various components when you can just tell it the time? The way you describe it, you'd have to wait for Friday to test the weekend-avoiding behaviour, which is just crazy. – itsbruce Sep 24 '13 at 9:54
  • You can either use all of those well-known techniques you linked to, giving your integration tests a 'test mode' with controlled date input, or just wait until Friday to run your tests. – Eric King Sep 24 '13 at 15:20
2

Make sure time is grabbed by a single function in a single library / by a well defined interface throughout your application's code, and provide a special "testing mode" in your application where that function delivers always the same sequence of date/time values. Run the application during the tests only in that testing mode. If you need different starting values for different tests, your "testing mode" will need that value as a configurable parameter.

there are always situations where the test cannot supply the data to work from

If you encounter such a situation, and you need some special data supplied for a specific test, then you have to change your product to make that possible. It is IMHO a fallacy that test frameworks or test environment should allow tests without a single change to the "subject under test". The idea of "maintenance hatches" was no invention of the software industry, and "design for testability" is something you have to work for, it does not come for free.

  • Indeed. One technique for doing this is to use Dependency Injection, a technique that is useful across programming in general, not just in testing. – Ciaran Gallagher Sep 24 '13 at 19:17
  • Yeah, this is one of the few occasions when Dependency Injection and Mock Objects really are an excellent idea. – Ross Patterson Sep 24 '13 at 21:28

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.