Heuristic: Test behaviour instead of X

February 3rd, 2021

I have found multiple ways of looking at this:

  1. behaviour vs methods

  2. behaviour vs state

  3. behaviour vs implementation

 


 

(1) Unit-Test Behaviour, Not Methods

focus on the features that the object under test should provide,

We need to know how to use the class to achieve a goal, not how to exercise all the paths through its code.

Describing Behavior, Not API Features

 

We need to know how to use the class to achieve a goal, not how to exercise all the paths through its code.

(src: Book: Growing Object Oriented Software, Guided By Tests - Steve Freeman & Nat Pryce)

 

So behaviour here is the protocol, instead of the interface (Model: interface vs protocol)

 


 

(2) Test behaviour instead of state

Another way of looking at it, is say 'test behaviour' means

  • test the behaviour like a user would use it

  • or

  • test the system as it would be used

 

instead of:

@Test cannot_create_duplicate_users() {

// arrange

...

var user = new User("a name")

userRepository.add(user)

 

// act

var secondUser = createUser("a name")

 

// assert

expect(secondUser).toBeNull()

expect(userRepository.users.filter(name ~= "a name")).toBe(user)

}

do this:

@Test cannot_create_duplicate_users() {

// arrange

...

 

// act

createUser("a name")

createUser("a name")

 

// assert

expect(DuplicateUsernameNotAllowed)

}

 

The first 'tests the implementation'

The second 'tests the behaviour'

 

With the second, you test the behaviour of the system.

'registering a user with the same name twice is not allowed'

 

With the first, you test

'if there is already a user with that name, you cannot create another user with that same name'

 


 

(3) Test behaviour instead of implementation

 

I have heard this phrase often.

I have used it occasionally.

But right now, it's still pretty vague to me.