Introduction to Unit Tests & its Importance

Writing Unit tests for your code can save your day, everyday.

If there was one thing which should have been emphasised on when you were beginning to code then it should have been the Unit Tests.

Once you understand the basics of a programming language and feel comfortable enough to write programs, that’s the time you should be looking into Unit Tests.

Let’s go ahead and get an introduction to Unit Tests.

What is Unit Test?

Unit tests are just helper programs that run the parts/units of your program. They make sure that your program is working as expected.
If you look at it, it’s just writing a function(test function) for your actual function. These test functions validate that your program is working as expected or not.

That’s it that’s what unit test is! But is it easy to write them?

Writing unit tests for your program is easy if you follow the coding guidelines, specially the loose coupling aspect of it.
The sooner you start unit tests, the easier it gets
. The statement holds true the other way round as well.

Why you should write Unit Tests?

Wouldn’t you like to know if the changes you made in your code will break some other part of the code ASAP! That’s what unit tests help in identifying.

Spending some time writing tests will save you time in the long run when you don’t have to worry about if your change breaks anything and make it much easier to make changes in the future.

It also gives you confidence as a team. In teams you would constantly find yourself working on someone else’s code. If the tests are present then you can run those tests to check if you broke anything.

One of the important reason why use should use unit tests is that it’s ability to provide feedback on your program. Of course it validates the functional correctness of your program but it also acts as a user of your code.

Confused! When you write unit tests, it is essentially a function trying to use your function. These test functions end up as a user for your code.
If you are easily able to write tests for your code then other programmers will also be able to extend your code. 

In the process of Unit test, you decouple your code such that your program ultimately becomes easily extendable. You will find yourself writing a lot of interfaces such that you are able to write the unit tests.

Unit tests make you sleep peacefully.

When do you write Unit Tests?

It’s best to start with the Unit tests from the beginning of your project. As you finish one logical block of your code, you should consider writing tests for it.

There are no hard and fast rule as of when to start writing unit tests. There are couple of approaches, following which you will know when to write unit tests. Lets discuss about them:

Write tests as soon as you finish a function. 

If you follow this approach, your project follows the programming principles from the beginning. When you write tests, thats when you find out how much your code structure is flawed.  It also makes you abide by the good programming practices.

For example : If your function does not take the dependencies needed for it’s execution as parameters, instead you initialise those dependencies in the function itself, then it becomes hard to test your function. And with that you miss out on loose coupling of your entire program.

The sooner your start writing the tests, the better your program follows the programming principles. 

Problem with this apporach

We tend to keep making changes to our functions till we get the entire feature working together as a whole and it becomes a pain to keep changing the tests as per the changed code.

That being said, if you think before you jump into coding and work out your function/method signatures before you code, you rarely find the need for too much change. If you follow this approach, the you will end up following one of the main guidelines of writing a program .i.e. think first, code later.

Write tests as you complete a feature

If you follow this approach, you will always have that feeling that your work is done, but you will need to improve your code by refactoring it and write tests for it.

Half of the time when we are assigned a problem to solve, we are more worried about getting the task done. And this is one of the first step when you code. Your program should work first.

Personally,  I end up following this approach. I want to follow the 1st approach we discussed, all the time. But that feeling of getting the things done keeps bringing me back to the 2nd approach. But I’ve got better at it with every passing day and fall back to the 1st approach quickly.

Problem with this approach

The downside of this approach is that by the time you finish your feature, you already have a lot of messy code structure. Now, if you start refactoring your code, it is double the work as well as you get reluctant towards writing tests for it. 

This approach is best suited when you have got ample amount of time for implementing a feature. You first implement the feature, when you write test, you’ll find out how bad of a work you have done on loose coupling and then you spend time on refactoring the code.

Test Driven Development.

With TDD, you first write the tests for your function and then implement the logic to make those tests pass. This is considered to be one of the best approaches, as it encourages the programmer to think out all the scenarios one should consider, write tests for them and then make those tests pass by implementing the logic of the function.

We will discuss one of these approach in how to section of this article. The TDD will be taken up in a separate article.

Where do you write Tests?

Unit tests walk hand in hand along with your code. 
Where to place your tests? Every programming language takes a different take on this, some ask you to separate your tests in a different folder. Some ask you to create test files adjacent to your source file.

For Java, tests are maintained inside same package against which you want to write the tests but they are maintained in different directory.

In case of Golang, the tests are kept adjacent to the source file. If you have a file app.go, then you would create the file app_test.go in the same directory.

So check out where your programming language asks you to put the test source files.

How do you write Unit Tests?

As I said earlier, Unit tests are easiest to write at the very beginning. The longer you avoid it, difficult it gets.

One of the approach discussed above is that you write test as soon as you write a function.

Now let’s see how we go about it!Consider you have a function which validates login.

The function you want to test

The below code is written in Golang.

func validateLogin(db DB, username string, password string) string{
  if db.Username != username{
  return "username not found"
  }else if password != password{
return "incorrect password"
}else{
return "login successful"
}
}

Now in order to write tests for it, all you need to do is call this function from another function.

In order to get the results and other test details, you can use the testing library of programming language of your choice. For Java, there is Junit, TestNG. For Golang it’s ‘testing’ package which comes as part of core library in Golang.

Using testing library to write tests

This is how your test code will look like:

import "testing"

func Test_validateConfig(t *testing.T) {

    expectedOutput := "login successful"
    db := DB{Username: "unit", Password: "test"}
    actualOutput := validateLogin(db, "unit", "test") //call the function you want to test
    if actualOutput != expectedOutput {
        t.Errorf("Expected output to be %s, got %s", expectedOutput, actualOutput)
    }
}

Since the actual and expected are same, the tests should pass. This how the output should look like:

PASS
ok github.com/sampler/a_test 0.006s

On test failure

If you change the expected output to ‘login failed’ then on failure you would get the output like shown below. 

— FAIL: Test_validateConfig (0.00s)
main_test.go:11: Expected output to be login failed, got login successful
FAIL
exit status 1
FAIL github.com/sampler/a_test 0.005s

Conclusion

There is more to unit testing then what we discussed. You will come across many more concepts like, Stubs, Mocks, Test Fixtures etc when you get into unit testing, but i hope this is good for your introduction to Unit Tests.

If you are looking for good book on unit test then I recommend that you read Art of Unit Testing by Roy Osherove. The book introduces and covers all the topics that one needs to know about unit testing. The book is available in C#, Java and Ruby.

Stay Connected

Please leave comment below if you feel that this article was helpful or if it can be improved in any way.

Stay connected on social network sites, or subscribe to be notified about the Test Driven Development post.  

Leave a Reply