Many of us think of separation of concerns when we design and code software but forget about it when we test. A common source of complexity in tests is a failure to separate the concerns.
For example, say you are creating a date-conversion library, two of the methods of which parse date strings into the underlying representation and format it into a display string. You could write a test that verifies the result by a round-trip, as in Listing 5-4.
describe('DateLib', function() {
it('converts the date back into itself', function() {
var expectedDate = '17 Apr 2008 10:00 +1000';
var actualDate = DateLib.format(
DateLib.parse(expectedDate));
expect(actualDate).toBe(expectedDate);
});
});
However, you are actually testing two independent pieces of functionality: the parsing and the formatting. Just because you can test them together does not mean you should. Instead, test them separately as in Listing 5-5.
describe('DateLib', function() {
it('parses a date properly', function() {
var expectedTimestamp = 1208390400000;
var actualDate = DateLib.parse('17 Apr 2008 10:00 +1000'),
expect(actualDate.getTime()).toBe(expectedTimestamp);
});
it('formats a timestamp properly for GMT', function() {
var expectedDateString = 'Thu, 17 Apr 2008 00:00:00 GMT';
var inputDate = new DateLib.Date(1208390400000);
expect(inputDate.toGMTString()).toBe(expectedDateString);
});
});
By testing your functionality separately, you verify each operation independently and catch the case in which one bug compensates for another. You also more directly express the way in which each piece of functionality should be used.
3.12.108.175