Photo by Jon Tyson on Unsplash
Anum Siddiqui
May 13, 2018 · 6 min read

As programmers we are continuously reminded that the world of coding is not too far from the real world, and that is why sometimes as developers we need this point of reference for things in the tech world to make sense. So I’m going to jump right into this topic called Test- Driven Development (TDD) and its shared similarity with antiseptics in surgery. Both TDD in programming and antiseptics in surgery are able to confront their opponents before introducing to the public their positive effects. Okay…so what does all this mean and where am I going with this?

Well one thing to realize is that the goal of antiseptics is to kill germs and bacteria in order to avoid spreading them between live tissues, which would ultimately lead to the development of diseases. TDD works like antiseptics, in which it works to deliver “clean code” with less bugs.

Testing is a key component when it comes to software development. Besides debugging, reading and writing test allows developers to gain clarity on what they are building, it simply lets you focus on the goal and eliminates anything that might be extra. TDD was introduced/rediscovered in 2003 by American software engineer Kent Beck. There are various aspects to using test- driven development and some principles that apply to are “keep it simple, stupid” (KISS) and “You aren’t gonna need it” (YAGNI). By focusing on writing the code that is necessary to pass the tests can result in clearer and cleaner designs.

So now that we know what Test- Driven Development can accomplish, how can we go about creating our own. Well, the general process of TDD is:

  1. Write a test that fails
  2. Write code to pass the test
  3. Refactor the code to make it “clean”
TDD Cycle

In test- driven development, each new feature begins with writing a test. Write a test that defines a function or improvements of a function. The first step is to run the test and to see it failing because there isn’t any adequate code to make it pass.

The next step is to write the code that will cause the test to pass. The important take away from this stage is that the new code may not be perfect but just sufficient enough to get the tests to pass.

The last step is to refactor the code. This means that the code must be cleaned up such that duplication must be removed in order for the code to be concise and efficient. This should lead to improving design and readability of your code.

Lets go ahead and implement how we can create a test using Test-Driven Development for our example: calculating password strength.

Step 1: Decide the inputs and outputs

Right now our goal is to calculate the password strength. The input for this is simple which is that it has to be the password. The output is also easy since it has to be some value describing the strength of the password. This can be accomplished by using a boolean, where the password is either strong or it isn’t.

Step 2: Choose function signature

Now that we know what our input is and what the output is, we need to decide on what parameter the function takes, and whether it returns something. In our example our parameter is the password.

var strong = isStrongPassword('password string goes here');

Step 3: Decide on one aspect of the functionality

In this stage, we want to think of what is the simplest possible behavior that we need to get closer to our goal? Or in another words, what lines of code can we add to bring the function closer to working. So for our example, the simplest rules for password strength would be having an empty string and for that the output should always be false when the password is empty.

Step 4: Implement test

In this step we want to focus on testing how the function behaves. We decided upon the function taking a password as its only parameter. We also decided that it returns a boolean to indicate whether the password was strong or not. In addition, we chose that for an empty password the result should always be false — to show that an empty password is weak. Now lets go ahead and plug everything we have done so far into a test:

describe('isPasswordStrong', function() {
it('should give negative result for empty string', function() {
var password = '';

var result = isPasswordStrong(password);

expect(result).to.be.false;
});
});

The syntax when creating tests are pretty simple. We start with “describe” and pass in the function we want to test. Followed by “describe” should come “it” where will begin to pass information about how our function should behave. Lastly we go ahead with “expect” which is pretty self-explanatory in which it shows what exactly our outcome should equal to, and in this case false if we have an empty string or no password.

Step 5: Implement Code

This step is where we’ll just add the smallest amount of code to make the test we created pass.

function isPasswordStrong(password) {
if(!password) {
return false;
}
}

If we wanted to continue developing the password strength function all we would do is go back to step 3, and chose the next small step to take. Then we would go ahead with Step 4 — add test, Step 5 — implement and Repeat!

Pro tips for TDD

☺Test Isolation — Test methods should be dependent upon one another. So when one of your tests breaks, then you know where to trace back to perform the fixes.

☺Test Scope — Choosing the proper scope of testing is important — it should be smaller than the whole application and it should test in the context of a class or package.

☺Put assertions first — Knowing what your tests is expected to do is very important.

☺Form a story behind the test — Try to define the story behind the tested functionality, for example what is the input/output and what is the purpose of this functionality?

Advantages of TDD

☺TDD deals with the human aspects of coding — Carelessness and forgetfulness. For example if we were to write all logic directly by line 200 we might forget why we are multiplying a variable with 10 at line 30. However by doing it incrementally, we are able to build our understanding. If you were to delete line 30, you can see which is test is failing and you would instantly know why.

☺ TDD will result in better coding practice — Focusing on the goal and what the function it set out to do, meanwhile making slight changes to make the the tests pass will allow you to refactor and create “cleaner” code.

☺With TDD, you’ll hardly miss things — When your create a requirement for your test to pass, you see it fail when you run it initially. When you add logic, you see it passing. But seeing it fail is important, so you know what broke your code.

☺ TDD saves you a lot of time(in the future) — Writing good tests with more and more conditions for your code will save you a lot of time of debugging in the future.

Conclusion:

Test- Driven Development just like antiseptics allow for less bacteria or in the coding world it allows for less bugs, higher quality software, and a razor focus. In addition TDD is about ensuring that the software’s internals are well designed, reusable and decoupled. TDD is not set out to write tests in a different way, however it is about design and thinking small, building incrementally and being critical about all possibilities.


Anum Siddiqui

Written by

New York native Full Stack Web Developer on the hunt for new opportunities and always hungry to learn!

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade