What is Test Driven Development (TDD)?

Sandesh Bodake

Why Test?

Writing tests is all about making sure that the code you write is working as expected and you did not break anything while adding new features or refactoring your code.

Automation is an integral part of software development then why should we continue doing manual tests again and again with chances of missing out on some test scenarios that are important. Instead, let the robots do the boring tasks for you.

If you have written a test suit, and the test suit passes, you can be confident that you are entire application behaves as expected.

Test Driven Development (TDD)

Tests are likely the best way to achieve confidence in the growing codebase. To amplify that confidence and achieve bigger wins in time-saving and code cleanliness we recommended writing code using a process TDD.

TDD is a process that uses tests to drive the design and development of your application. It begins with a development cycle called Red, Green, Refactor.

Red, Green, Refactor

Red, Green, Refactor flowRed, Green, Refactor flow

Let’s take an example to understand the red, green and refactor flow

For e.g. Imagine you want to create a function sort_array() that can sort an array in ascending order

Red

Think about what you want to develop.

You don’t have to know what your code will look like at this point, you have to know what it will do. Write a test that covers your functionality you would like to implement, you should see it fail.

INPUT: [34, 3, 12, 2]

OUTPUT: [2, 3, 12, 34]

When you run the test you will see an error like this.

Green

Think about how to make your tests pass

Now time to resolve the failing tests step by step, read the error message from the failing test and write code that will fix the current error.

After implementing the sort_array() function, we should see a passing tests message that looks like following.

Refactor

Think about how to improve your existing implementation

If we write another test case to sort an array, we should see failing second test message that looks like following.

Again Red,

The expected result does not match the actual result we are getting …

expected: [3, 8, 21, 99]
     got: [2, 3, 12, 34]

This is because we are returning first sorted array not caring for other examples(not implemented any sorting algorithm). Take a moment to think about how to approach refactoring sort_array() function. write code for sort an array in ascending order.

Now if you run rspec again you will see our both test cases are passing

As we refactor sort_array(), When we complete our refactoring process and run our suite again, we should able to receive the following output

Basically in this stage clean up your code, reducing any duplication you may have introduced. make your code modular and efficient. you should feel confident enough in the test you have written that you can make your changes without breaking anything(Refactoring).

Example

Let’s go through the example to understand how to use TDD strategy.

Take an example of employee check-in, once employee checkin to the office received message check-in completed on his HR Application. (This is a very basic example for testing purpose)

Prerequisites:

  • Ruby

  • Rspec gem

  • OOPS concept (basic understanding of class, instance etc)

Step 1] Install Rspec

Rspec is a DSL(Domain Specific Language) a testing framework written in Ruby.

gem install rspec

This command will install rspec gem in your ruby gem folder

Step 2] Initialize Rspec

rspec --init

This will create two things

spec_helper.rb file always loaded when you ruining rspec test cases and .rspec make sure of that.

All set we are now ready to go

Photo by Braden Collum on UnsplashPhoto by Braden Collum on Unsplash

Let’s start writing test cases

Our First test file will be called employee_spec.rb and we are going to test 4 things

1] Creates an employee object?

2] employee having a check_in() method?

3] employee invoke the method check_in()?

4] And the method check_in() returns message?

Add Test

We start adding simple test firstly and watch its failing.

Next, run rspec command in my project folder you can see the test we wrote is falling.

Test1Test1

The error uninitialized constant Employee is tell us that Employee class not defined anywhere that’s why rspec gave us this error.

Pass Test

Now, start writing some code and try to pass that test.

Refactor

Now It’s time to refactor our code, I created lib/employee.rb that keep our classes in segregated. In order to run your test case, you will need to include file in spec_helper.rb

Running rspec now should give us the same result

Test1Test1

Repeat the process for the next unit test

Next Step to ensure that Employee responds to method check_in(). Here we test first whether check_in() method present or not then we will check whether that method responding expected response.

Next, run rspec command in my project folder you can see the test we wrote is falling.

Test2Test2

Create method check_in() in the Employee class to pass the test

Running rspec now (you have to be in your project folder in terminal) we can see our test cases passed successfully

Test2Test2

Now, Build a working method and Test It

We run the test now and see the following method:

The expected result does not match the actual result we are getting …

expected: "Check-in completed"
     got: nil

Now we refactor check_in() method,

Run rspec again we will see our all test cases working fine.

Test3Test3

Note: This is a basic example taken for testing purpose which always returns Check-in completed message once invoke check_in method. we can add is_check_in_complted variable of boolean type to the employee class to keep a track of employee checked-in or not.

Summary:

  • Understand the employee specifications

  • Identify objects and their behaviours

  • Write the test first, and see it fail

  • Write some code to pass the test

  • Run the test

  • Refactor

Benefits of TDD

Confidence

TDD is all about confidence. writing your tests first and only writing a response to failing tests cases, you can trust that all of our production code is covered and the confidence gives you the power to quickly and easily change or refactor your code without fear of it breaking.

Time Savings

TDD can also lead to time savings over traditional testing. Writing your test upfront gives you useful error messages to follow to a finished feature. You save time thinking of what to do next because your test tells you!

Flow

Once you write your test, the test failures continuously tell you what to do next and your code becomes more modular and scalable.

Improved Design

TDD helps you recognize coupling upfront. Object-oriented design principles, like dependency injection, help you write your code in ways that reduce this coupling, making your code easier to test.

Documentation

Tests are always a good point to start for new joiners in the team to understand what the application is supposed to do.


CONCLUSION

In this article, you saw how TDD can improve confidence that your code is working as expected. if you use red, green, refactor approach in large software projects you will find yourself saving a lot of time, while implementing a more robust solution than you otherwise would have.

At Scalereal We believe in Sharing and Open Source.

So, If you found this helpful please give some claps 👏 and share it with everyone.

Sharing is Caring!

Thank you ;)