When I had my first internship, I was tasked with maintaining a legacy ASP application. This included everything on the front-end, through the application layer, using Visual Basic and VBScript, as well as the database that was primarily used as a datastore for XML.
What are interns for, though, right?
I’m kidding: I actually like the idea of having junior programmers work on maintenance tasks or bugs at first to get a feel for where things are (or were) before jumping into where they are headed.
At the same time, I was also learning and reading a good bit about unit testing. It was past the time when it was “the hot new thing,” but it had hit a point where a lot of people were talking about it.
It was finding its way into day-to-day conversations. It was becoming part of the curriculum of any software engineering course or material that any software engineer should know. It was coming up in interviews, conversations, blog posts, books, and so on.
It was becoming impossible to escape.
Either you knew how to unit test, you knew TDD, or you didn’t.
- if you didn’t, then you might get an SMH from a potential employer,
- you might get a condescending comment from a peer,
- or you might get roped into a conversation covered in sheer excitement from that guy over in the cube over who’s been aiming for 100% code coverage since the company rolled out the testing infrastructure.
I’m not bashing testing (because I think it has its place and I think we need to know how to write them) and I’m not downplaying having a significant level of code coverage in a given application (because it is important).
But the amount of testing can be done is also related to a handful of others things that programmers don’t often seem to discuss: time, budget, and pragmatism.
This post is already getting longer than what some of us like to read (are you reading this sentence, even?), so I don’t wax poetic about this for too long but if you have the time, entertain me.
The point that I’m ultimately working towards is that I don’t think it’s always as simple as basically “just write the damn unit tests.”
There are other things at work beyond just that each of which influences what we’re doing.
Not Writing Unit Tests
Late last week, I read an article titled No Excuses, Write Unit Tests. These types of titles are usually set up to grab attention. Success!
The article provides a rationale as to why we need to be writing unit tests and why there’s really no excuse as to why we shouldn’t be doing so.
A Disclaimer (That Shouldn’t Be Necessary)
Before I proceed, I think the following disclaimer is necessary because the Internet loves some trolls and hate pieces and Twitter wars and all of that.
- I don’t dislike The Practical Developer. Obviously, I’m a fan.
- I don’t think anything negative about the author, @jackmarchant10, of the article. He makes compelling points that are completely valid.
- I think the article provided some good food for thought (thus this particular post).
I think I’ve covered all of my bases but put it this way:
If you assume I’m writing this with a negative position, don’t. And if you think I’m “out to get” someone, I’m not.
I’m just sharing my side of this topic. That’s it.
Back On Point
There are a lot of good points mentioned in the article and I think, if you haven’t already, you need to read it.
One point I want to address from the article, specifically as someone who’s running a small business strictly aimed and building solutions for small teams and small businesses is this:
Unit testing your code takes some extra time upfront, because of course, you need to write extra code – the tests.
Then, weeks or months go by after you’ve written those tests and you make a change to a function that was tested, and the test breaks. Bugger. Now you’ve got to go in and fix the test.
Just write the damn tests.
Generally speaking, writing testable code is something we should strive for, but when you’re working in a small business and you’re working on fixed cost projects or on hourly-rate projects, this doesn’t always work.
Simply put, clients don’t always have the budget for:
- the requested features,
- the performance,
- the architecture,
- and the time.
It’s the whole project management triangle (but remixed a bit for our own industry).
And I know how the arguments go: It’s up to us to convince them, you can do it in a second version, etc.
But it doesn’t always go that way.
- sometimes there isn’t a second version,
- sometimes there isn’t time,
- sometimes features aren’t negotiable (though they often are),
- and so on.
Personally, I bring up the idea of testing to my clients to see if it’s something they want. I explain the reasons for them, the benefits of them, and so on. But it comes at a cost and we typically go from there.
And That’s My Ultimate Point
Sometimes it’s a tradeoff of features, sometimes it’s a tradeoff in time, and sometimes it inflates the budget. Sometimes companies are interested, sometimes they are not.
And, as mentioned earlier, that’s my ultimate point:
I don’t think it’s always as simple as “just write the damn tests.”
This doesn’t mean I don’t want to and it doesn’t mean that I don’t think they are necessary.
It also doesn’t mean I can’t bring in prior experience to write classes in a way that are amenable to testing. But I also have the business needs to think about and sometimes, writing unit tests are not in scope.
This may be where I’m wrong, but I think enterprise-level teams have more flexibility in this area than small businesses. And that’s okay (I mean, it’s not an “us versus them” type of thing), it’s just the nature of the industry.
Sure, I’d love to be able to implement TDD or something similar across the board and have all of my code unit tested.
But not all projects at my level lend themselves to these. So though I’ll grant the advantages of unit testing and what they can do for software, I can’t come all the way to “just write the damn tests” nor can I say that I think it’s pragmatic to do so.
And perhaps I’ll cover that last sentence in another post.
Just before drafting this post, I came across an article Kent Beck : “I get paid for code that works, not for tests” which is from 2013 (why it’s showing up now is anyone’s guess, but it’s timely, nonetheless).
For those who aren’t familiar with Kent Beck, he’s one of the pioneers of unit testing.
One of the relevant quotes:
I get paid for code that works, not for tests, so my philosophy is to test as little as possible to reach a given level of confidence (I suspect this level of confidence is high compared to industry standards, but that could just be hubris).
I think it’s worth remembering: Even if you’re budget doesn’t support nor account for a high-level of test coverage, aim for a level of confidence.