Unit Test Best Practices – Test-Driven Development

Unit Testing Best Practices Test Driven Development

Today in this article, we will understand What is Unit tests and Unit Test Best Practices in Software Development.

We will cover the below aspects in the below article,

Why Unit Tests?

Your application/service consists of a bunch of functionalities built together to perform business operations. These small/large bunch of functionality together makes your application complete in a sense.

It’s important these small individual functionalities are robust enough to make sure your application performs best in a real production environment.

unit test best practices

How will you make sure these small pieces in your application will be robust??

There is no other better way than Unit Test. Unit Test is the FIRST thing you should do to make your application robust. Tests are termed unit tests because here the emphasis is on each individual piece of application. Each small individual method is important and represents a unit and hence needs to be tested in isolation.

Where to start?

We understand the concept of Unit Tests but there is always confusion on “Where to start”. Isn’t it?

Unit Testing checklist

I have simplified as below,

All public functions within a class (created by you) require a unit test.

So if you want to start somewhere in an existing application, then start with a small class and a simple method in the class.

What is Unit test

Now we got an answer for where to start.

Let’s look into a few best practices in general that we can follow. Please understand there are many best practices before we get crazed about this. but there are a few best-of-best practices that should be enough to write better unit test cases.

Here we really need not have to bother about Test First vs Code First. These best practices are generic enough to be applied to any approach of development you are using.

Best Practices for Unit Testing

In an all-to-remember unit test cases should follow the FIRST principle,

F = Fast

I = Isolated

R = Repeatable

S = Self-checking

T = Timely

This FIRST approach is explained in detail as below,

Best practices for Unit Testing

1. Unit test cases should be Fast.

Yes – every test should run within milliseconds. Fast enough to execute within 10 ms can be considered a good test,

Why? What does it really mean to Developer? See below,

  • Build your method/functions as small as possible.
  • If method/functions exist already, refactor it immediately (pretty simple to say but go and get in buy-in from your Manager 🙂 for refactoring the code)
  • Small functions are easier to test and maintain.
  • Small functions promote reading and reuse.
  • Small functions help avoid hidden bugs that come with large functions. Large functions are sometimes impossible to test due to large dependencies and affect badly on code coverage.

So this best practice really has a broader meaning which drives all goodies to your code.

Do Not Stop here …Here is what will make you think to design a better method/function if you are following Test Driven Development (TDD) or even make you think redesign/refactoring your existing legacy code.

2. Unit test cases should be isolated

  • Unit test cases are meant only for a given function and its business logic in a given class.
  • If that method/functions (Let’s say A() )calls any other method/functions ( let’s say B())then you write separate unit tests for that dependency(i.e B()). That means you need to mock B() within A() to make isolation.
  • Each unit test should be stateless and doesn’t depend on other unit tests by any means.

3. Unit Test cases should be Repeatable.

  • This lot more depend on the second principle i.e Unit test cases are isolated.
  • You get the same result for any number of times test cases are executed.
  • You get the same result for any order in which test cases are executed as they are stateless in nature.
  • That means you get the same result for all reasons except when breaking changes introduced by developers.
  • Unit test cases find breaking changes right ahead of time.

4. Unit test cases should be Self Checking.

  • Already written unit test cases will be kept on checking for any breaking changes introduced by any developers.
  • Right ahead of time intimation of a new bug introduced in the code by failing Unit test cases.
  • Self-checking will work on the local machine or could work on the build server as part of the CI-CD pipeline.

5. Unit test cases should be Timely

  • A unit test should be written in a timely manner and should not take more time than the actual development of business functionality.
  • Convinced? Here are the questions clarifying how much time should be spent on Unit test writing.

If your unit test is taking more time to write,

  • That means you need to follow the first principle concept very seriously.
  • Method/functions is not small enough to test all scenarios easily.
  • Need to design/refactor your class, method/functions.
  • That means need to pitch in hard negotiating on Design..and lastly, do not stop here .. go get the buy-in.

Unit test cases have + ve impact in the long run and do provide a lot of benefits on the maintenance side (shift left) for early identification of bugs and issues.

If working on existing code, unit test cases will give you a lot of early signals of coding issues and opportunities for improvements.

It’s important to implement all those if possible.

Remember maintenance is a big fat elephant and always eats away most of the project budget in SDLC.

Some additional best practices and guidelines for Unit Test cases,

  • Test only public members. These public members can be used to test private members implicitly.

  • Do not test auto-generated code-Example – Entity framework scaffolding, WSDL generated proxy class members, etc.
  • Create stateless unit test cases.
  • The order of execution of unit test cases is not important.
  • Use code coverage tools for measuring code coverage.
  • Mock everything which is a dependency.
  • Interface-based programming favors unit test cases. Always program by abstraction.
  • Use Test-driven development with the Test first approach.
  • Do not test private members/functions/methods. Try testing them using the public method instead.

References :

Do you have any comments or ideas or any better suggestions to share?

Please sound off your comments below.

Happy Coding !!



Please bookmark this page and share it with your friends. Please Subscribe to the blog to receive notifications on freshly published(2024) best practices and guidelines for software design and development.



Leave a Reply

Your email address will not be published. Required fields are marked *