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 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 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.
Test1
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
Test1
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.
Test2
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
Test2
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.
Test3
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 ;)