Making Time-Dependent Features Testable (c#)

Person waiting and waiting

Developers always strive to provide 100% automated test coverage for the code they write. However, one particular class of features is quite difficult to test — those that depend on current time, in one way or another. In this post I would like to share a simple and efficient technique that I have been using now for years that provides an elegant solution.

Let’s bring up an example — an expiring token in c#:

Nothing special, and here is the straight-forward test code:

Making test run hang for 20 minutes just literally wasting time? That’s hardly feasible.

We can move the constant 20 (token lifetime in minutes) to config file (which we should do anyway), and then try to set much lower value for testing, but this does not eliminate the problem completely.

In manual testing for an entire application, QA engineers sometimes actually wait for this long, for a lack of a better way to test it. Another method sometimes used — changing machine time for a short interval; but it is tricky, and it is a race against the network time service that will reset the time back.

So how we can make it easier? The idea is to create a wrapper for the DateTime.UtcNow that allows 'shifting' the current time for an application — and using the wrapped time throughout the code.

Here is the static time wrapper:

This class works as a time machine — you can shift time forward or back, provided all access to current time in the application is done through the AppTime.UtcNow static property.

The new Token code:

Testing the expiration now becomes trivial:

It’s not just for expiring things — I suggest that you use this AppTime.UtcNow everywhere, just for consistency. Just establish the rule — no DateTime.UtcNow, ever, only AppTime.

Using this technique in manual testing

It might seem this technique is only usable in automated code-based testing. But you can use it in manual testing process as well. Let’s take a Web application as an example. We can provide a special ‘hidden’ back-door page in our app, enabled only in test environment, that allows the tester/user to set the time offset in the AppTime class on the server. It does not have to be a page, just a REST endpoint that you can hit from the browser and send offset value in a query parameter.

Let’s see how a QA person can test that login/session expires in 20 minutes due to inactivity.

  1. Login to the app.
  2. Click a few things, everything works
  3. Open another tab in browser, hit URL like “http://myapp/set-time-offset?offset=1260" (1260 -> 21 minutes in seconds)
  4. Back to the app, click something that invokes the server. The app should show message “session expired” and redirect to login page.

I have been using this class for years now, in all applications I write. I hope you find this technique useful too.

This article was originally published on codeproject.com.

.NET Developer with 20+ years of experience. Open source: Irony (parsing engine), VITA (.NET ORM), NGraphQL (GraphQL engine). @Microsoft, Cloud Security