It’s always amazing to see how people find it hard to compromise, to nuance their opinions about things. And I’m probably the first one finding it hard. But when it comes to software practices, boy it’s annoying.
I was talking to a colleague of mine the other day, we were talking about unit testing and other best practices, and I boldly and shamelessly said to him: “I haven’t written any unit test on this project.” He stared at me with a bit of surprise, then with a bit of disappointment and finally with a bit of something like… disgust!
“What!? No tests, but why? How can you pretend to be a software architect if you don’t practice systematic unit testing?! Oh my god!…”
My first reaction was a furious urge to hit him in the face. But then I remembered myself a few years back, and I did nothing but leave him in his panic state and disappointment.
When I started working as a consultant, I had already written a few applications in engineering school, but strangely enough they didn’t really talked to us about software quality, agile methodologies and other modern best practices. We did formal programming, Prolog, we reprogrammed a memory management unit and wrote a compiler for a subset of the Java language, but nothing useful ;o).So when I discovered that some people were actually doing things in a rational way, to write better software, I was at the same time impressed and overwhelmed by all of that. Design patterns, continuous integration, test-driven development… I had never seen those in the real world, but I read a lot of books and websites and it seemed so nice that I came to think that it was the only way. And of course I was wrong.Fortunately, I started working on real-world projects, dealing with all sorts of external constraints. And no matter how hard I tried to impose “my” great software best practices, everybody looked at me like an alien because they just didn’t understand why I was talking about all this stuff. So when I was fed up with complaining about no one understanding what should be done, I realized that they were at least right to wonder. Why are things like TDD, CI or Design Patterns so important?
When you read so many articles explaining to you how to write unit tests, they all seem to assume that unit-testing is good in itself, as if it was some kind of axiom. But the truth is that no matter how good they are, writing them and maintaining them is a real pain, right? Lesson learned: when something is painful but good for you, there’s gotta be a better way. But a better way to what?
Because for me that’s the real problem: losing sight of the objective. Unit-testing and TDD are not good in themselves, they are just one best practice which allows you to improve the overall quality and robustness of your code. Why so? Because when you write your tests before the corresponding functional code, you considerably reduce the probability of a bug in the functional code. And robustness comes from the fact that whenever the implementation of a given functionality is modified over time, unit tests are there to ensure that the overall result will remain the same. Fine! But how about a better way?
First, let’s talk about reducing the probability of bugs. The main problem with code is that it’s written by us, human beings. And like it or not, we are faillible, we make mistakes, and the more we think we don’t, the more we actually do. Now rather than testing everything that we write, isn’t there a way to reduce the amount of code that we have to write? I can tell you that: there is a way!
I already see my colleague smiling if he reads this, because I’m so obsessive about this “way” that it becomes ridiculous. Take care, here comes the dirty words: code generation. Of course I’m not talking about the kind of code generation that just displaces the problem elsewhere, that is in diagrams that are the ont-to-one mapping of your code. I’m talking of a higher level of code generation, I’m talking of Model-Driven Architecture.
I know that many programmers don’t like it, have read many articles about and introductions to MDA without ever going further, mostly because programmers like to… program, not draw. And I can understand that. And if you’re in that situation, then you’re stuck with test-driven development… or any other “way” you can find. But if you like to have a better view of the big picture, if you want to accelerate your development and increase the robustness and quality of your code, then have a look at this (my favourite), this and this. You might be surprised.
Will it completely replace unit tests? I don’t think so, but it can create a situation in which you have so dramatically reduced the amount of code to test, that it can be interesting to wonder whether it’s still worth the effort.
My main point is, software best practices are nothing without the goal they allow you to reach, and forgetting that is the best way to stop looking for better ways, to stop innovation and progress.