@should do test-driven development

May 11, 2014

I recently described the @should taglet created by OpenMRS that helped the community adopt and sustain better testing practices.  Mário asked a good question about test-driven development (TDD):

I believe that BDD and TDD are very connected (except, when talking about integration tests). But I don’t see how [we can] use TDD if we need to create the @should tags first. Could you please clarify a little bit how that would work?Mário Areias

While I don’t think we’re doing much TDD in the OpenMRS Community at this point, it would be great to evolve this direction.  The real question is: will the @should tags that helped us start testing our code become an impediment to TDD?  I don’t think so.

Let’s try a simple example to see how we could be TDD-ish with @should tags.  Imagine that we want to be able to get the age in years of a person:

class Person {
  Integer getAge(Date onDate) {
    return 0; // TODO: return age
  }
}

Before we write any code, we describe the expected behavior.  To keep the example brief, I’ll just describe a couple expected behaviors:

class Person {
  /**
   * Returns person's age in years.
   * @should return null for date before birthdate
   * @should not round up age
   */
  Integer getAge(Date onDate) {
    return 0; // TODO: return age
  }
}

Next, we invoke the Behavior Test Generator plugin to automatically do the busy work of generating the skeleton for our unit tests.

class PersonTest {
  void getAge_shouldReturnNullForDateBeforeBirthdate() {
    // TODO: write unit test
  }
  void getAge_shouldNotRoundUpAge() {
    // TODO: write unit test
  }
}

So, now we can write our unit tests and see them fail, like any newborn tests in TDD would do.  Granted, in this example, you don’t technically start with the test code, but you can start with describing behavior (using @should tags) prior to writing code and using those tests to drive development.  So, yes, we start with @should tags; however, @should tags, can precede any actual code, since they are effectively shorthand for the tests we are writing before coding.

2 Comments