Can we skip unit tests for infrastructural code?

Almost always we end up with infrastructural code in our projects. That is extension code on top of the framework that we’re using internally, added so that the main functional code of the app is cleaner, clearer, shorter, and also more testable – since it it separated from its infrastructural dependencies through custom “mockable” interfaces that we expose and that might otherwise be missing.

(For example, many times we design and use a generic – although probably app specific – data access layer that internally accesses a database and provides data and saves back data changes to and from the app services.)

The infrastructural code tends to become complex, and will eventually also contain logic, so we might consider it a good candidate for unit testing, isn’t it? But then one would immediately think again: won’t such tests be very difficult to write? Does it really worth to write them?

To answer, let’s first think a bit about the reasons of unit testing in the first place:

  • We want to find issues early. Yes, usually writing unit tests help us detect issues fast, immediately after or even before the code of the tested unit is complete, i.e. before running it together with other parts of the system.
    • But in practice if the unit test is difficult to write – as it happens many times with infrastructural code – it’s very probable that it would actually take more time to get to the problem through unit testing, than compared to simply running integration tests – using the first functional unit and the tested infrastructural one – or even to just running an early system test on the development machine with the debugger!
  • We want to be prepared for maintenance. Yes, proper unit testing ensures that other team members (and ourselves in the future) don’t break existing functionality without knowing – when changes are requested by customers or when we decide to refactor code for any other reason.
    • For infrastructural code this is indeed important, but in my opinion the difficulty of writing unit tests isn’t beaten by this reason alone! Instead, I have seen that:
      • infrastructural code tends to change very rarely,
      • and even when it does it is immediately retested through integration tests from functional areas and through system tests that do need the infrastructure in place and working well anyway.
  • We document our code. Yes, if we write unit tests with a good naming technique, their names can turn into documentation!
    • But for infrastructure we should also write and maintain some better documentation anyway!

However, because I’m sure I won’t convince anyone that one may safely add infrastructural code into his or her app without any measures against regression on forseen maintenance in that area, I want to propose an alternative:

We can somehow lock the infrastructural code so that whenever a change is really needed there, it is done with extra care and closer code review.

(Actually, as an anti-regression technique, unit testing is also a mechanism to lock code, as if one needs to change tested code, he or she would be forced to ensure all tests still pass or are updated themselves to run against the new logic – fully assumed and signed upon by changing the tests.)

Currently development environments don’t seem to offer a lock code mechanism as it would be needed by my proposal, but I think it won’t be very difficult to implement one as an IDE add-on.

For example, I am thinking of a [LockCode(Hash=”…”)] attribute added on an infrastructural C# service class by simply right clicking the code in that class and selecting a Lock code command in the context menu. The argument value would be computed automatically by loading the class code and computing a hash on it.

  • Now if somebody would change that class, the hash won’t be correct anymore, and in this case the environment could trigger a high priority warning. Of course, this warning would appear also if the code refactoring is 100% OK and the changed class would run exactly as before, i.e. if all unit tests would have still worked in case they existed. But from my point of view this is something that we can live with instead of the hassle of having to implement and maintain unit tests there!
  • Furthermore, we can think of new project rules, such as requiring double code reviews for code changes that include adding or updating hash values, to increase maintenance safety.
  • With such an approach we will gain a lot of time from skipping the task of writing complex and difficult unit tests on that rarely changing code, process that might otherwise require adapters and wrappers over the internal core framework objects to actually obtain testability! And we will release faster than our competition!

What do you think? Would such a locking code mechanism be useful in your case?

Advertisements

About Sorin Dolha

My passion is software development, but I also like physics.
This entry was posted in Architecture and tagged , . Bookmark the permalink.

Add a reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s