the home of test-first teaching

About Test-First Teaching

Why Test-First Teaching?









Unit Testing

Unit Testing refers to writing a set of functions that sit next to a given module of program code. These functions run a series of tests that assure, more-or-less thoroughly, that the program code performs as it is supposed to.

For example, assume there is a function called add that takes two integers as parameters, adds them together, and returns their sum. There might be one unit test that calls add with 2 and 3, and makes sure the result is 5. There might be additional unit tests that "push the envelope" in various other ways, testing its behavior with large numbers, negative numbers, illegal parameters (e.g. strings), and so forth.

Once a full suite of unit tests is developed, it is good practice to run these tests as often as possible.

Test-Driven Development

Test-Driven Development (sometimes called Test-First Development or Test-Driven Design) is the practice of writing the unit tests first, before you write a single line of implementation code. While this may seem like putting the cart before the horse, there are several good reasons why you might want to do this:

  1. Design. It forces you to think first about the design of the interface to the code, instead of jumping straight to the implementation. Having a well-designed interface is often more important than having an efficient implementation.
  2. Discipline. Writing tests is often seen as a chore; writing the tests first guarantees that at the end of the day you will have written a suite of unit tests (rather than leaving them until the end and possibly never getting around to it).
  3. Less Work. If you apply a tight cycle of write one test, then write the code to implement that test, then write the next test, your code ends up growing organically. This often (though not always) leads to less wasted effort; you end up writing all the code you need, and none of the code you don't need.

Testing Frameworks

A Testing Framework is a tool or library that provides a backdrop for writing tests.

For example, to implement a test in the JUnit framework for Java, you write a class that extends the common TestCase superclass. Each method in your subclass that begins with the word "test" is a separate unit test. You then run the JUnit tool (both graphical and text versions are provided) and it loads your class and executes each test method in turn, monitoring the results and providing feedback.

Using RSpec for Ruby, you use the keywords describe and it to build a nested set of tests (also called "specs" or "examples" in the RSpec lexicon).

There are several testing frameworks in use for Ruby today:

  • Test::Unit is included with Ruby 1.8, and follows the "xUnit" conventions
  • Minitest is included with Ruby 1.9, and allows both xUnit and RSpec style tests
  • RSpec, which is used in this project, has more concise syntax and can be used in the same project, but creates a separate suite of tests, called "specs"
  • in Cucumber, tests are written not in Ruby but in a language designed for tests

There are also many testing libraries which can be used inside any of the frameworks listed above:

  • Wrong provides a universal assert (or expect) that inspects your code and automatically tells you details of why it failed
  • shoulda provides a "chaining DSL" for representing assertions, similar to RSpec
  • rr is a Mock Object library

Join the Conversation

Join our test-first teaching mailing list.
