Saturday, February 10, 2007

Unit tests can be fun!

Here's a snippet of testing code from a university assignment I did last term where we had to create a model of an alarm clock using finite state machines and then test using the FSM testing techniques we learned in class. This is Java 5 code with some JUnit goodness.

/**
* It's 21:30 and I'm going to bed. I set the alarm time for 06:00 and then
* sleep until the damn thing wakes me up, but I don't want to get up just
* yet and I think 4 more minutes will change my mood today from
* "didn't get enough sleep" to "downright chipper" and so I slam my hand in
* the general direction of the drowse button (it has an 80%, no 70% chance
* of hitting it the first time) and then wake up a new man 4.2 minutes
* later, turning off the alarm functionality until I need it again the
* following night.
*/
@Test
public void SetTickRingDrowseTickRingStop ( ) {
// set clock time from 01:00 to 21:30
super.SwitchTimeSet();
// that is to say add 20 hours
for (int c = 0; c < 20; c++) {
super.HourButtonClick();
}
// and 30 minutes
for (int c = 0; c < 30; c++) {
super.MinuteButtonClick();
}
areEqual(21, 30, super.clockTime);

// set switch to Run
super.SwitchRun();

// set alarm time from 13:00 to 06:00
super.SwitchAlarmSet();
// which is to add 11 + 6 hours
for (int c = 0; c < 11 + 6; c++) {
super.HourButtonClick();
}
areEqual(06, 00, super.alarmTime);

// set switch to Run
super.SwitchRun();
assertTrue(super.IsAlarmOn());

// go to sleep for 8.5 hours
for (int c= 0; c < 8.5 * 60; c++) {
super.TickMinute();
}
areEqual(06, 00, super.clockTime);

// whoa, it's ringing!
assertTrue(super.IsTriggered());
assertTrue(super.IsRinging());
assertFalse(super.IsDrowsing());

// leave me alone for 240 more seconds!
super.DrowseButtonClick();
for ( int c = 0; c < 4; c++ ) {
assertTrue(super.IsTriggered());
assertFalse(super.IsRinging());
assertTrue(super.IsDrowsing());
super.TickMinute();
}
areEqual(06, 04, super.clockTime);

// whoa, it's ringing again!
assertTrue(super.IsTriggered());
assertTrue(super.IsRinging());
assertFalse(super.IsDrowsing());

// that's it, I'm getting up and turning this thing off
super.SwitchAlarmOff();
assertFalse(super.IsAlarmOn());
}

The test depends on some @Before method which resets the model (i.e. makes it just like the alarm clock just had batteries put in for the first time) and thus the the initial clock time is 01:00 and the initial alarm time is 13:00.  The model was created from observing the behaviour of an old Westclox travel alarm clock.

2 comments:

Andrew said...

On the topic of unit tests - I started playing with the unit testing capabilities of VS 2005 last week. Pretty neat.

Olivier Dagenais said...

Andrew: would you mind blogging about your experiences, as it seems that MSTest is worse than NUnit, although on the other hand there appears to be some unit Test creation facilities not presently offered by TestDrive.NET, which I, incidentally enough, attempted to add to Eclipse??

Thanks!