The talk at this year's Devoxx I enjoyed the most, was the keynote of Uncle Bob aka Robert C. Martin. The whole talk was brilliant but there was one part I particularly enjoyed. As a reaction on his claim that testing is enormously crucial for a software Craftsman, he was confronted with a question from the audience, stating that ensuring code has a large test coverage, also comes with a lot of hastle maintaining those tests. He then replied with the single coolest answer on the topic ever:
"Ok what's the alternative? We'll just dance in circles around our code claiming that it works then shall we?!?"
It's funny because it's true. To me, it seemed that in the way he replied there was a bitter undertone. As if he had been asked this question far too many times and far too few people listened. To get the proper coding standard, testing is a serious business.
For my first contract I was lucky enough to end up in a fully compliant TDD project. The methodology was taken serious, along with the other eXtreme programming principles such as pair programming.
We swiched keyboards every 15 minutes and always started with the writing of a test. In the beginning this really helped to think about the contract of my class. What is it supposed to do? For me, after a couple of years the test 'first' became less useful since thinking on the interface of your class comes natural after some time. As long as you test your class well, you'll refactor it until it's working and readable.
However, we're not paid for working code, we're paid for bug free (*) code. What does it mean to test your class well? What all developers, including myself, constantly have to keep in mind, is to not forget to also negative test.
On a system level negative testing is referred to as tests trying to break the system, for instance massive load tests. I'm referring to negative testing on a unit level. That's seeing how your code (CUT) responds to different behaviour than expected. The non-standard scenarios if you like.
For instance, let's say a method takes in an account number as a parameter. What will the method do if the account number format is invalid. Or if the format is valid but the account can not be found in the persistent store. Or if it's found but no longer active?
Negative testing might sound logically or easy to do, but two things get in the way; first of all, you need to stay disciplined enough (read: don't be too lazy too implement the additional test cases). All...the...time.
Second of all, it's hard to negative test code that you've written yourself. It is inherently human to find the code you've written two minutes ago, easy and clear code. It does what it needs to do right? When you're pair programming, your pair might have an interesting vision on code you wrote, providing you with a little more feedback. This usually results in additional test cases.
But not everyone is pairing. You might be the only developer on the team. What helps for me is the blackbox testing approach: looking at the interfaces you're dealing with, but not at the implementation.
For instance, on an individual class level, think about how heavy your methods depend on their parameters. If a parameter is optional for a method, how does your code react when it's not there? What if it's there but it contains a functionally wrong value? If a parameter is absolutely crucial and it's not there, does this indicate a bug? If it does, you might want to fail early and add an explicit not null check as your first statement.
On a higher level, if your class depends the output of collaborating classes, is the return value of that class always as expected? What happens when it's not?
Of course integration tests cover a lot of the scenarios at a certain point in time. However, you never know when your piece of code will be called in future or different scenarios.
That's why negative testing is important.
I'm interested in hearing about your experience in negative testing, so comments are welcome.
(*) This is an utopia of course, but we should at least strive towards it.
No comments:
Post a Comment