Tweaking automated checks - part two

28/01/2016 20:48
A second thing that I am keeping an eye on while writing my checks is significance of anything I use in the checks. To explain why, I'll give you an example that isn't related to code but shows my take on significance:
A couple of days back our team had a meeting and one of us prepared some data on a whiteboard. Realizing that the pen he started with was almost empty, he continued with another pen that had another colour. As he had a bit of time before the last person arrived, he erased the hard-to-read start and rewrote the beginning with the new pen. Now there was some space between the first part and the second and to the newly arrived people he said "It was written in red, therefore the space."
Although that sentence was absolutely true, the red color was not significant for the space. In a written check I wouldn't settle for much less than "the first pen I used was empty, so I rewrote the beginning". 
There are mainly two reasons why I would read a check after I wrote it: Either the rules changed and I have to maintain the check to adapt to new functionality (btw, that shouldn't happen too often, otherwise you probably want to rethink your approach) or the check went red and I need to find out what's wrong. If I have to read the whole code and need to ask around to find out about the meaning of things in a check, it becomes a problem itself. So I want to write my checks in a way that help me in both situations.
In case of a fire you don't want to read long instructions of the fire extinguisher. You need it to work without much thought. 
The thing that helps me out the most here are: names. If you haven't read Clean Code by Robert C. Martin yet, I recommend it. It has a whole chapter about naming things in coding. For our problem at hand that means: Give meaningful names:
val threeCustomers = new Array(new Customer(), new Customer(), new Customer())
What do you think about this? Is it important that there are exactly three customers? Is it important that there are only new customers involved? If it's only important that there are more than one, you can call it "several" or "few". If the actual customer doesn't play a significant role, you can call it "randomCustomer" or "anyCustomer". Be specific about what your object is. And what it is not. Give it a meaningful name that will help you and others reading the code when you have to.
Instead of using magical numbers directly, you can give them a name and thus explain which significance they have. Instead of dividing something by 3600L*1000L*24L, divide it by millisPerDay, and the next reader won't misunderstand or take any time to calculate. Although it seems like yet another small change, I am pretty sure, those small things add up fast. 
Missing information
There is something that many seem to overlook when looking for significance. And I have wasted a lot of time finding the answer to such cases. If it is significant that something is missing, not there or didn't happen, the check should contain that. Even if it means that we repeat ourselves and our code won't be DRY
Let's look at an example: Let's assume a new Customer is instantiated with an orderCount of 0. If I want to write a check that assures we offer a special discount to a customer with an orderCount of 0, I wouldn't just write 
new Customer() shouldBe applicableForDiscount
My take would be:
val aCustomerWithoutOrders = {
    val c = new Customer()
    c.orderCount = 0
aCustomerWithoutOrders shouldBe applicableForDiscount
This is significantly more code in this (simplified) case. But it also tells me more: The importance of the orderCount being exactly 0 is emphazised. When that check fails, I do not have to look into how a new Customer is instantiated. I spot the additional assignment immediately.
So, mind what is significant for your checks and what is not. And emphasize what might be missed so you have the extinguisher ready when there is a fire.
There are more parts of this mini series coming. In combination this little improvement gets even more powerful. Feel free to comment.
See the first post within this series here and the next one here.



comments powered by Disqus