Learning to Love TDD

Rachel Lum
Jul 8, 2019 · 5 min read
Image for post
Image for post
Red, Green, Refactor

What if I told you there was a way to significantly reduce potential bugs in production code? Undoubtedly, most programmers would not hesitate to jump on this opportunity no matter the cost. As many programmers know, it can be quite the unpleasant experience for a user to encounter a bug, and for the development team to attempt to recreate the bug and fix it in production as quickly as possible.

Well lucky for us, there is a solution, but it is no magic pill. It is…

Test Driven Development (TDD)

Image for post
Image for post
Testing

Test Driven Development, or TDD, is a software engineering practice of writing unit tests before writing the production code. The mission of TDD is to provide structure to the coding process and as a result, write cleaner, more purposeful code. This practice stems from the Extreme Programming (XP) method emerging from the Manifesto for Agile Software Development.

Below are two key values of the Agile Manifesto pertaining directly to TDD state:

- Working software over comprehensive documentation

- Responding to change over following a plan

Test driven development differs from the V-model, a software development life cycle, in that TDD values “test first” approach versus that of the V-model’s “test last” approach, which has proven to be much less efficient.

The Process

TDD is otherwise known as the “red, green, refactor” cycle method, working in small increments to get your tests to pass. The red represents the unit test you write that fail at first, the green is the production code you write to get the test to pass as soon as possible, and refactor, well, is pretty much self explanatory. The cycle should last no more than ten minutes, and the idea is that you are staying succinct in what you want for your features, and you can gain confidence in refactoring because you know that everything will work as long as it continues passing the regression tests.

That being said, the resulting production code should still follow standard software engineering conventions such as KISS (keep it simple, stupid), and DRY (don’t repeat yourself). Additionally, writing good tests takes practice, and should follow the FIRST acronym (fast, independent, repeatable, self-validating, timely) as mentioned in Hacker Noon’s article.

There are two types of tests including unit tests and integration tests. Simply put, unit tests ensure that each feature works independently, whereas integration tests check if all the features work together in a simulation of the execution environment.

Getting Started with Writing Tests

To write and run tests with your code, you can choose from many excellent tools. There is an abundance of options out there, so I would suggest asking your peers or coworkers what their companies use and get started that way. It depends on what language you use, what features you want, and what your budget is. For Ruby, many use RSpec, which is what I will be using in the example below.

If you are just getting started with TDD, I recommend following a tutorial. I started following the tutorial on Upcase created and led by Thoughtbot developers Harry Schwartz and Ian Anderson. I was inspired by their tutorial for the following example.

Example

For our example, we are going to create a calculator. Specifically, we want to create a new instance of a calculator that has the functionality to subtract two given numbers.

So let’s start by writing the tests. Schwartz and Anderson recommend writing at least two tests for a specific function to ensure that our code works as intended.

describe Calculator do
describe "#sub" # => instance method, just a string
it "returns the difference of its two arguments" do
calc = Calculator.new
expect(calc.sub(10,2)).to eq(8)
end
it "returns the difference of two different arguments" do
calc = Calculator.new

expect(calc.sub(5, 1).to eq(4)
end
end
end

So we’ve written the tests, and as you may notice, a lot of the tests are just strings. That is so you, the developer, can have flexibility with your tests. The main keywords of RSpec include describe, it, do, expect, .to, and eq() . The tests should fail, and the command line should printuninitialized constant Calculator.

We do not have a Calculator class. So now, let’s write the production code to make the firs test pass! Remember, we are working in tiny increments, making one test pass at a time. Try not to let your ego get ahead of you — write the tests, and write the minimal code to make the tests pass.

class Calculator
end

Now our error reads undefined method 'sub' for #<Calculator> . So, there is no instance method sub for our Calculator class. Let’s write it in. Again, one thing at a time, let’s make this test pass.

class Calculator
def sub(a, b)
end
end

Our next error: expect(calc.sub(10, 2)).to eq(8).

expected: 8 got: nil

Evidently, we could make this code pass by hardcoding the value 8 in the method sub, but what about our second test? Well, we could write a conditional to return a certain value given two specific inputs, but let’s just give the people what they want. If you know an elegant reusable method off-hand, then use it. If not, then you can always refactor later.

class Calculator
def sub(a, b)
a - b
end
end

Ta-da! Our tests pass, and everything is green.

Conclusion

Of course, this was a short introduction with an extremely simple example of the TDD method. Hopefully, you gained a small introduction to what the TDD process is like. Testing does take a bit of practice and investment in time, but it is all the more worth it to write cleaner code. As you practice more, the better you will get, and the more purposeful your tests will be. I will be continuing my tutorial on Upcase and will continue to share more about my journey here.

The Startup

Medium's largest active publication, followed by +752K people. Follow to join our community.

Rachel Lum

Written by

Full stack web developer with passions for dance, fitness, health, math, communication, and technology.

The Startup

Medium's largest active publication, followed by +752K people. Follow to join our community.

Rachel Lum

Written by

Full stack web developer with passions for dance, fitness, health, math, communication, and technology.

The Startup

Medium's largest active publication, followed by +752K people. Follow to join our community.

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store