Unit-test evolution
This is an example of unit-test evolution which I presented on recent devclub.eu workshop.Let’s consider 3 revisions of the same unit-test class.This is the first revision of this class:
public class ReferenceNumberTest {
@Test
public void testValidate() {
assertFalse( ReferenceNumber.validate("1234567890123") );
assertFalse( ReferenceNumber.validate("1234567") );
assertTrue( ReferenceNumber.validate("12345678") );
}
}
We call it a typical unit-test.At some moment, some developer decides to apply some TDD best practices and split this test-method into 3 with some meaningful names.This is what he got:
public class ReferenceNumberTest {
@Test
public void testTooLong() {
String len13 = "1234567891111";
assertEquals(len13.length(), 13);
assertEquals(ReferenceNumber.validate(len13), false);
}
@Test
public void testTooShort() {
String len7 = "1234567";
assertEquals(len7.length(), 7);
assertEquals(ReferenceNumber.validate(len7), false);
}
@Test
public void testOk() {
String len8 = "12345678";
assertEquals(len8.length(), 8);
assertEquals(ReferenceNumber.validate(len8), true);
String len12 = "123456789111";
assertEquals(len12.length(), 12);
assertEquals(ReferenceNumber.validate(len12), true);
}
}
We call it good unit-test.After some time, some developer decides that even this good unit-test is not human-readable and does not provide enough information about how class ReferenceNumber should work. He continued splitting and renaming.This is what he got at the end:
public class ReferenceNumberTest {
@Test
public void nullIsNotValidReferenceNumber() {
assertFalse(ReferenceNumber.validate(null));
}
@Test
public void referenceNumberShouldBeShorterThan13() {
assertFalse(ReferenceNumber.validate("1234567890123"));
}
@Test
public void referenceNumberShouldBeLongerThan7() {
assertFalse(ReferenceNumber.validate("1234567"));
}
@Test
public void referenceNumberShouldContainOnlyNumbers() {
assertFalse(ReferenceNumber.validate("1234567ab"));
assertFalse(ReferenceNumber.validate("abcdefghi"));
assertFalse(ReferenceNumber.validate("---------"));
assertFalse(ReferenceNumber.validate(" "));
}
@Test
public void validReferenceNumberExamples() {
assertTrue(ReferenceNumber.validate("12345678"));
assertTrue(ReferenceNumber.validate("123456789"));
assertTrue(ReferenceNumber.validate("1234567890"));
assertTrue(ReferenceNumber.validate("12345678901"));
assertTrue(ReferenceNumber.validate("123456789012"));
}
}
We call it BDD style specification.And finally, the most interesting part. During preparing for the workshop, I have discovered that I haven’t copied the original source code of the class ReferenceNumber being tested. Panic! One day left! I had to urgently re-create it from scratch!Now look at these 3 test-classes, and imagine, which of them helped me to create class ReferenceNumber.
Our recent stories
The Codeborne Christmas beer brewing diaries
It was a sunny day in September. Quite warm for that time of year. We were sitting with my colleague Tiit on the roof terrace in the Codeborne office as we do every now and then. I ask him for advice on occasion - after all, what are the more experienced colleagues good for otherwise?
“Backing up” a good product owner
One of the key players in most successful agile projects is a product owner, at least in Codeborne’s practice. Our practice stretches for more than 15 years, during which we have successfully delivered over 100 projects.
Unleashing the power - How Creos partnered with Codeborne to change Luxembourg's energy sector
Creos Luxembourg involved Codeborne in its journey to modernize Luxembourg’s energy sector