Writing testable Javascript-1

Photo by David Travis on Unsplash

Writing code for a new feature or for a completely new product is fine and it is easy too. But when you wanna ship it, and find the cases for which your code survives and fails takes up most of your development time. Typically time spent introducing a new feature has a ratio of 25:25:50. That is 25% for Analysis, 25% for Design, and development, and finally 50% of testing and bug fixing. Here you can see that about 50% of the time of shipping a product goes for testing and fixing bugs. And yes it is necessary to spend more time on testing because it is important to ensure that only the qualified product gets shipped and others are sent back for fixing. But is it necessary to spend a whole lot of time testing when there are tools and frameworks like Mocha, Jasmine, Jest etc available for helping us out in it?

But it doesn't mean that simply using one of those tools will test your product and gives back you result. We as a developer have some work to do with it. As a developer, our part in testing goes to these kinds of testing.
  • Unit testing
  • Integration testing
  • e2e testing
Unit literally means most individual components in anything. So unit testing means testing the individual unit of your program. Typically it can be a function, which is the most individual component of a program. Or it can be a module or a class too. And integration testing means integrating all the components tested in unit testing and running through new testing. So to make these tests happen we developer have some part and that is writing testable code. In this context I will be taking examples of front end development, so the code and example would most probably be in Javascript. So let's get into it. How to write testable javascript?

Thumb rule: Separate business logic and presentation logic.

This is a simple factorial program that returns the factorial of the given number from the text box and outputs in an alert message. Note here that the function is binded with the button click event as an anonymous function.
$('#button1').bind('click', function(event) {
number = document.getElementById('textBox').value;
let factorial = 1;
for (let i = 1; i <= number; i++) {
factorial *= i;
}
alert(factorial);
});

Suddenly if your code doesn't work as you expected, what will you do to debug it?
  • You have to set up your DOM.
  • You have to give the input manually in the text box.
  • Click the button to get your output in the alert message.
You won't feel the problem here because the function here is so simple and you can debug it with two or three trails. But imagine a deep long algorithm which takes some second to give you the answer from the time you have clicked your button. It takes a complete day or many to debug your simple mistake.
function getFactByRecursion(number) {
if(number == 1 || number == 0) {
return 1;
}
else {
return number * getFactByRecursion(number-1);
}
}

Consider the above code. This code does the same thing(by recursion) but without anonymity. By doing so you can independently run this function without setting up the DOM and going through a hell of steps to run this function. And also you can get the input from the text box and pass it as an argument to this function and receive the result and display it in the alert message. Remember now the testing your business logic doesn't require your DOM.

This code is the business logic where the work is to find the factorial of the given number. The presentation logic is to get the input from the text box and display the output in an alert box when the button is clicked. Remember the presentation logic may change. Today the input is from a textbox, tomorrow it may be from a voice recognized input. The output today is in the alert box, tomorrow it may be in an audio output or it can be anything. But the business logic remains the same.

Rule 2: Give a function a single purpose

Don't dump your function with too many works. Make it do what the name says. Or name it what it does. If it has to display the output of the user name, just make it do that alone. It must not care to add any salutation or making first name last and last name first or changing cases. If it has to do that, make it a separate function and then compose back again.

displayName: function(name) {
console.log(name);
},

addSalutation: function(name, gender) {
if (gender == 'male') {
name = 'Mr.' + name;
}
else {
name = 'Ms.' + name;
}
return name;
},

makeFirstNameLast: function(fullName) {
let firstName = fullName.substring(0, fullName.indexOf(' '));
let lastName = fullName.substring(fullName.indexOf(' ') + 1);
fullName = lastName + ' ' + firstName;
return fullName;
},

composedFunction: function(name, gender) {
name = this.makeFirstNameLast(name);
name = this.addSalutaion(name, gender);
this.displayName(name);
}

Few more rules to go. To be continued. 
Writing testable Javascript-2

-Balaji SV


Comments

  1. Replies
    1. Thanks for taking time to read and exalt it. Hope it helps.

      Delete
  2. Hence proved zoho zoho emp🔥🔥🔥🔥Seems good💯

    ReplyDelete

Post a Comment