background

Test-Driven Development (TDD)

What is TDD?

To put it simply, Test-Driven Development is a software development process by which test cases are written and implemented before the code. These test cases are usually in the form of unit tests, but there are other special forms of TDD that do not use unit tests, such as Acceptance TDD which uses acceptance test cases.

Why use TDD?

Test-driven development is less about testing and more about efficient development, however, it manages to accomplish both. The primary goal behind writing test cases before code is that as one is writing the test cases, he or she is also procuring critical business domain logic that may have otherwise been overlooked. Let's take this thought a little further with an example.

TDD Example

The Problem Domain

For this example, we are going to use the cliche program, FizzBuzz. The FizzBuss problem domain is as follows:

  • Start at number 1 and iterate up to and including 100
  • If the number is divisible by 3, print "Fizz"
  • If the number is divisible by 5, print "Buzz"
  • If the number is not divisble by 3 and not divisible by 5, print the number.

Writing Test Cases: Round 1

This problem seems simple. I think we only need to cover three scenarios:

  • When the number is divisible by 3
  • When the number is divisible by 5
  • When the number is not divsible by 3 and not divisible by 5

Let's try writing some unit-test cases in JUnit 3:

void testFizzBuzz() {
    assertEquals("Fizz", myObject.fizzBuzz(3));
    assertEquals("Fizz", myObject.fizzBuzz(99));
    assertEquals("Buzz", myObject.fizzBuzz(5));
    assertEquals("Buzz", myObject.fizzBuzz(100));
    assertEquals(1, myObject.fizzBuzz(1));
    assertEquals(98, myObject.fizzBuzz(98));
}

This test case covers valid cases at the extremes of the input range. Maybe we should add a few more to cover some of the optimal input conditions:

void testFizzBuzz() {
    assertEquals("Fizz", myObject.fizzBuzz(3));
    assertEquals("Fizz", myObject.fizzBuzz(99));
    assertEquals("Buzz", myObject.fizzBuzz(5));
    assertEquals("Buzz", myObject.fizzBuzz(100));
    assertEquals(1, myObject.fizzBuzz(1));
    assertEquals(98, myObject.fizzBuzz(98));
    //new test cases
    assertEquals("Fizz", myObject.fizzBuzz(30));
    assertEquals("Buzz", myObject.fizzBuzz(50));
    assertEquals(51, myObject.fizzBuzz(51));
}

Writing Test Cases: Round 2

Looking back at the test case from Round 1, I noticed a problem. There is an ambiguity in one of these test cases. Do you see it? The number 30 is divisble by 3 and by 5. This means it should print "Fizz" and "Buzz", but right now, I'm only testing for "Fizz." I'll change my test-case to match the new insight I've gained of them problem domain:

void testFizzBuzz() {
    assertEquals("Fizz", myObject.fizzBuzz(3));
    assertEquals("Fizz", myObject.fizzBuzz(99));
    assertEquals("Buzz", myObject.fizzBuzz(5));
    assertEquals("Buzz", myObject.fizzBuzz(100));
    assertEquals(1, myObject.fizzBuzz(1));
    assertEquals(98, myObject.fizzBuzz(98));
    //new test cases
    assertEquals("FizzBuzz", myObject.fizzBuzz(30));
    assertEquals("Buzz", myObject.fizzBuzz(50));
    assertEquals(51, myObject.fizzBuzz(51));
}

I'm satisfied with this test case. I think it's time to start coding.

Coding

I read the problem domain, I wrote my test cases, now it's time to start coding. I now know there are 4 scenarios I need to look out for: divisible by 3, divisible by 5, divisible by 3 and 5, and not diisible by 3 and not divisble by 5.

 void fizzBuzz(int value) {
   bool isDivisibleBy3 = (value % 3 == 0);
   bool isDivisibleBy5 = (value % 5 == 0);

   if (isDivisibleBy3) {
       System.print("Fizz");
   }
   if (isDivisibleBy5) {
       System.print("Buzz");
   }
   if (!isDivisibleBy3 && !isDivisibleBy5) {
       System.print(value);
   }

   System.print('\n');
 }

Running the Tests

The goal behind TDD is to spend less time in this phase. By writing the test cases before coding, I wrote the code to satisfy those tests and therfore wrote the least amount of code necessary. This resulted in clean, simple, and elegant code.

Conclusion

This example was very simple and I'm sure using TDD for it may seem trivial to many. However, the goal of the example was to demonstrate that unlike many other forms of testing, the most innovative part of TDD is not executing the test cases, but writing them. By doing so, the requirements are read over more throroughly and special cases like boundary and extreme values are evaluated more carefully. This ultimately results in faster development time and a quicker transition from QA to release.


Mar 21st, 2014 Brayden Willenborg

MarkDown

Getting Started

You're in! Nice. We've put together a little post to introduce you to the Ghost editor and get you started. Go ahead and edit this post to get going and learn how it all works!

Writing in markdown is really easy. In the left hand panel of Ghost, you simply write as you normally would. Where appropriate, you can use formatting shortcuts to style your content. For example, a list:

  • Item number one
  • Item number two
    • A nested item
  • A final item

or with numbers!

  1. Remember to buy some milk
  2. Drink the milk
  3. Tweet that I remembered to buy the milk, and drank it

Want to link to a source? No problem. If you paste in url, like http://ghost.org - it'll automatically be linked up. But if you want to customise your anchor text, you can do that too! Here's a link to the Ghost website. Neat.

What about Images?

Images work too! Already know the URL of the image you want to include in your article? Simply paste it in like this to make it show up:

The Ghost Logo

Not sure which image you want to use yet? That's ok too. Leave yourself a descriptive placeholder and keep writing. Come back later and drag and drop the image in to upload:

Quoting

Sometimes a link isn't enough, you want to quote someone on what they've said. It was probably very wisdomous. Is wisdomous a word? Find out in a future release when we introduce spellcheck! For now - it's definitely a word.

Wisdomous - it's definitely a word.


Feb 26th, 2014 Brayden Willenborg

Unit Testing in C++

Working with Code

Got a streak of geek? We've got you covered there, too. You can write inline <code> blocks really easily with back ticks. Want to show off something more comprehensive? 4 spaces of indentation gets you there.

.awesome-thing {
    display: block;
    width: 100%;
}

Ready for a Break?

Throw 3 or more dashes down on any new line and you've got yourself a fancy new divider. Aw yeah.


Advanced Usage

There's one fantastic secret about Markdown. If you want, you can write plain old HTML and it'll still work! Very flexible.

That should be enough to get you started. Have fun - and let us know what you think :)


Feb 25th, 2014 Brayden Willenborg

Test-Driven Development (TDD)
MarkDown
Unit Testing in C++