JS Ext

Friday, January 30, 2015

Story of non-testable code

At my company, we have a library that allows us to read data from a content management server.  The library will check for new content periodically.  This allows us to make content changes (change the label on a button or the legal disclaimers on the bottom of the page) without going through a full code elevation.  We just change the content in the CMS and the JVMs automatically pick up the content change.

This library was not implemented in a testable way, however.  Instead of being a Spring bean, or a singleton, or another of a hundred other ways, the developers show to make it a static class.  The class has all static methods.  We can still technically mock the class; we just need to use a tool like PowerMock.  This class is used all over the place, so what should be simple unit tests end up containing dozens of lines of mock statements.

I was tasked to make a change to a REST call.  The change needed to be made, but it was a very risky change.  I decided to heavily unit test the REST call to make sure my change didn't break anything.  If the content library was written in a testable way, I would have the opportunity to create my own implementation of it.  In that implementation, I would return the content chunks I care about, and ignore the content chunks I don't care about.  Instead, the code was written statically.  I had to use PowerMock to mock out every single time that REST call called the content system.  I cared about 3 pieces of content.  I had to mock out 30 pieces of content, per unit test.  I had 27 test cases.  I put all the mocking for the content I don't care about in a common method that each test case could call.  This isn't the worst part of the situation though.

A few weeks later, someone else had to make changes to the same REST call.  Their changes had nothing to do with my changes.  The build broke because my unit tests were failing.  The unit tests didn't actually find a problem.  What they found was new content being requested that the mocking system didn't know about.  This is why so many developers hate unit tests.  This particular developer spent more time trying to fix my unit test than writing the code they were supposed to make.  This gave me a bad reputation because I'm the guy who wrote the crappy unit test.

Fast forward even more and another developer is making changes to the same REST call.  This time they are making changes in the code that I made changes in.  Once again the unit tests fail.  This time, they fail for two reasons: 1) new content and 2) a regression was introduced.  Since these unit tests have a reputation for being brittle and the developer didn't want to deal with unit tests that give false positives, he removed the unit tests.  This was a major regression that would have cost lots of money to fix if it made its way into production.  Luckily it was caught in manual testing.

Automated unit testing can be a wonderful thing.  It can save lots of money.  There is a big but, though.  It can only do those things when it is done right.  Forcing the wrong type of unit testing makes the situation worse.

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.