Hello dear readers, being a Junior to Mid Developer myself I've been of course faced to this weird "fear" of testing my code. Maybe it isn't fear, maybe we just do not talk much about it.
But either way I've been recently learning to program in Golang and I want it to do it seriously, in the right way. That's why this time I did not skip the tests subject.
In this article I want to show how easily testing our code can be, it is not an effort, specially with the testing standard package incorporated in Go.
As an example I am going to implement and test a method that checks if a phrase is a heterogram or not.
An heterogram is basically a word that doesn't contain a repeating letter. However it can contain multiple spaces or symbols like hyphens (-).
I've started by creating a Golang app using go modules,
go mod init my app. Then i've created a package heterogram containing an
heterogram.gowith an IsHeterogram() method and also I've created an
heterogram_test.gofile for our testing functions. Finally a main.go file where I could possibly import my heterogram method to run it.
heterogram_test.gofile let's import the golang testing package and create a function TestIsHeterogram, passing in parameter a pointer to the struct T of that package to manage test state and support formatted test logs. We're going to define an input that is the string we want to check and also what we excepect of it.
For example, the string (input) toto is expected to return false because the "o" letter is present 2 times.
So if IsHeterogram("toto") returns false the test passes and if it returns true the tests fails.
Now to start using this very simple test we need to actually start implementing our heterogram method.
As you may have guessed our method is going to receive a string in parameter, we then are going to to loop trough that string and check each character. We are using the range keyword in our loop that returns a rune , that is basically a superset of the ASCII table that can handle more characters. We are going to append each character (runes) to a slice named exists to store the existing letters.
Now we need to check if the following character (rune) of our loop is present in our slice exists, if it is then we return false. For that we are going to write another helper function that we are going to call simply contains(). This method is going to loop trough a slice of runes and check if a rune is present or not.
Now back to IsHeterogram() we can check if a character of our string is already in the exists slice. If it does exists then we return false,if not at the end of our loop our method is going to return true.
Let's go back to our test function and run it. To run a test simply run
go test inside of the heterogram package (cd into that folder) or use your IDE to run it.
We can see that our test has passed. Now let's try something, let's see if our method is well tested, change the input from "toto" to "Alpha" and run the test again. The world "Alpha" has two "a" so the test should pass right ? It should return false.
Well as we can see it has failed, the result for "Alpha" is true. And this shows that our method IsHeterogram is not finished, we didn't handled the uppercase letters. See how testing can improve our development ?\
Let's quickly fix our method by lowercase all of our inputs using the package strings.
Okay perfect, what if we wanted to test the case of "six-year-old" for example, remember that hyphens (-) are allowed. Well we could change again the input variable but let me show a better way to handle multiple test cases 🙂.
We have tested both "toto" and "Alpha" but now we also want to test double hyphens with "six-year-old" that should be true and maybe an empty string as well "" that should be true too. We are starting to have multiple cases to test and instead of changing manually let's create a
case_test.go file in our heterogram package where we can store this test cases.
We are going to do this by defining a struct with 3 fields: description, input and expected. We are going to pass in as many cases as we want. Then all we have to do is go back to our TestHeterogram function and replace the previous code by a for loop that ranges our struct of cases.
See how simple our test file looks now. We can run all our tests cases in a single time.
go test one last time let's fix our IsHeterogram method to handle double hyphens. To do this before before checking if the exists slice contains our letter I am going to check if it is actually a letter by using the unicode package.
Okay now we are ready hit that
go test one final time and all our tests should pass 🙂.
Thank you all for reading this article, if you have any questions don't hesitate to contact me. For those of you who are more visual learners I've filmed a video about this you can go check it out here 😀.
See you soon ! 🙂