Agile methodology techniques: Unit test, automation and test-driven development

Yvette Francino explains the basics of unit test, automation and test-driven development. Test-driven development (TDD) is a form of unit testing, originating from the agile methodology XP. The tests are written and executed using short iterations, originating with a test case before the code is written.

I've heard the term, "test-driven development" (TDD) bantered around quite a bit, but I still was unclear exactly what the term meant or how TDD differed from traditional unit test. When the book Test-Driven JavaScript Development by Christian Johansen landed in my library, I took the opportunity to explore the subject more deeply by conducting a two-part interview with Johansen. But in this tip, we start first with the basics by describing unit test, automation and TDD.

What is unit test?

Let's start by defining "unit test." Unit testing is the testing of a small "unit" of code, typically performed by the developer of the code that's being tested. Ideally, the unit tests themselves are coded so that they can be run over and over again in an automated way.

For example, let's say you have a piece of code that is supposed to accept a date representing a birthday. Your application wants to find out the age (in days) of the person who has this birthday. The pseudo-code for this routine might look something like this:


If birthday NOT valid format

Return error message: Invalid date format

today = system date

Convert today and birthday to integers that represent days

If birthday > today

Return error message: Birthday cannot be in future

If birthday == today

Return message: Today is your Birthday! Happy Birthday!

today – birthday = age_in_days

Return message: You are age_in_days days old


Now, in order to unit test this code thoroughly, the developer would want to make sure each line of code is executed and validate that it performs as expected. In order to do that, he'd need tests in which the birthday was entered with an invalid format, tests where the birthday was in the future, a test where the birthday was the current date, and tests where the birthday was in the past. If the program accepted the birthday as input from the terminal, he might manually test by calling GetAge with various parameters such as GetAge(2/29/60), GetAge(10204020), GetAge(20/52/2011) and checking that the outputs are correct.

Now automate

However, rather than manually entering tests and checking for validity, it would be better to write a program (Maybe GetAgeTest) that would execute with different values for birthday. Part of the test would include validation that the proper message (or output) was returned and then a pass or fail for each test. Failures might even automatically send out notifications to a designated contact.

Note that sometimes, as in this case, the results are going to vary because the system date will change. So for tests with valid dates, the age in number of days will increase over time. If the programmer hasn't taken this into account, the test case might report back a failure because the result is different from the day before. Thus, the programmer must make sure that their automated test cases accurately test for static as well as dynamic conditions.

Once these tests are written, they can easily be executed as regression tests. Later, if the GetAge function changes internally, GetAgeTest will ensure that all the test conditions are still executing correctly.

So what is test-driven development?

Test-driven development (TDD) is a type of unit test which originated with the agile methodology called Extreme Programming (XP). Similar to the above example, TDD uses automated tests that can then be used as regression tests whenever a new build is done. One difference, however, between TDD and traditional unit testing is that the test programs are written before the application code is written. In other words, it is the test that is driving the development or application code, rather than the other way around. The test, of course, will fail, until the application code is written which will fulfill the conditions of the test.

The traditional approach to software development is to do the design, code, and then test. TDD uses much more of an iterative approach. Rather than wait until the entire design is completed to start coding, and wait until the code is complete to start testing, test, design, and development are all done in very short iterations.TDD helps designs evolve.

As Johansen describes in  Test-Driven JavaScript Development, each iteration of code development includes four steps:


  • Write a test
  • Run tests; watch the new test fail
  • Make the test pass
  • Refactor to remove duplication

The first step, writing the test, requires the developer to determine the outcome of a small segment of code. The test, in a sense, becomes the documentation of the requirement. Rather than investing in what Johansen terms the "Big Design Up Front" of traditional development, the design evolves in the act of writing the code that will satisfy the conditions of the test. Refactoring is the term used for removing duplication or improving design. As long as the test still passes, the internal code can be optimized by refactoring.

This, of course, is the very basic explanation of the concept of unit testing, automation and TDD. However, Test-Driven JavaScript Development will step you through detailed code and testing frameworks, allowing you to get a closer look at TDD in depth.

For more information see the SSQ Learning Guide, which has a large compilation of articles on unit testing and TDD.

Dig Deeper on Topics Archive