Writing “enough” tests for a Ruby function

Claudio B.
Clutter Developers
Published in
2 min readOct 10, 2018

As developers, we often wonder how many tests we should write for our code. If we write too many test cases, we will end up with 1,000 lines of code–hard to read and hard to maintain. If we only write a couple of test cases, we will feel uncertain that the we have covered all the edge cases.

My suggestion is to think about the possible types of input and then write a couple of tests for each type. This is what I consider enough testing.

Prices ending in “9” have a hypnotic effect. Walk into any store and you will notice a myriad of items tagged as $19, $29, or $99. The strategy is pretty straightforward: take the original price and round it (up or down) to the closest dollar-amount ending in 9.

How do we implement such a method in Ruby? Here is a first draft:

To prove that this code works as intended, we write two test cases that reflect our expectations. We expect $12 to be rounded down to $9, while we expect $17 to be rounded up to $19:

We install RSpec with gem install rspec and then run the tests:

Yay, the tests are passing! Are we done here? Are these all the tests we need?

In the code above, we have only written tests for two amounts: $12 and $17. These numbers are both small, integer, and positive. They might represent the typical input that we expect, but we should not forget about the other cases.

In other words, we should write some test cases for big numbers, floating numbers, and non-positive numbers, and see if the tests still pass:

Notice how RSpec’s syntax helps in clearly identifying the groups of test cases. Let’s run the tests now and check the output:

Oops, an edge case is failing! We don’t normally expect a price to be $0; but if that happens, it should be rounded as $0, not as -$1. More generally, if the argument is less than or equal to $0, we should simply round it as $0.

Fixing the method to make the test pass is pretty straightforward. Our final code looks like this:

In the end, we have 3 lines of code for the method and 16 lines of code for the tests. The tests are very readable and the grouping helps us understand what are our expectations for the method. This is what I consider enough testing.

If you enjoyed this article, please share with your friends. If you are looking to join an amazing team of Ruby developers, check our current openings at Clutter.

--

--