In part 1 you learned how to refactor (change) test code to reduce duplication of the expected behaviour.

In part 2 you learn simple rules to ensure test reuse and give you flexibility. These rules will improve the maintainability of your tests, meaning you can respond quickly to user stories! Read on to learn the rules and how to apply them.

In part 2 you learn simple rules to ensure test reuse and give you flexibility. These rules will improve the maintainability of your tests, meaning you can respond quickly to user stories! Read on to learn the rules and how to apply them.

**A simple example**

Imagine you are testing a calculator class. Here are your first two tests for the add function:

assert( 6 == add( 2, 4 ) )

assert( -6 == add( -2, -4 ) )

**A change request comes in!**

"Due to customer requirements, the add command will now round to the nearest 10 instead"

You go through every test updating the expected value as follows.

assert( 10 == add( 2, 4 ) )

assert( -10 == add( -2, -4 ) )Imagine a thousand tests for add - the change would take ages!

**Another change request comes in!**

"Due to a customer request, the add command will also return the amount the value was rounded by"

You go through every test updating the expected value and comparison code as follows.

result = add( 2, 4 ); assert( 10 == result.sum && 4 == result.rounding )

result = add( -2, -4 ); assert( -10 == result.sum && 4 == result.rounding )

Imagine if we have a thousand tests for add! The effort of updating them is tedious and error prone!

**How do you think about tests?**

Here is your first test again:

assert( 6 == add( 2, 4 ) )

It is a valid test. When you wrote the test, you were thinking about three things:

**The scenario**- let's try adding 2+4**The expected behaviour**- The method adds the values making 6**The comparison logic**- I can compare numbers by using the == operator.

Here is your second test again:

assert( -6 == add( -2, -4 ) )

**The scenario**- let's try adding -2+-4**The expected behaviour**- The method adds the values making -6**The comparison logic**- I can compare numbers by using the == operator.

- The scenario you have
**changed**(intentionally) - The expected behaviour is the
**same**(although the expected result is different) - The comparison logic is the
**same**

As a Software Engineer in Test, you would like to reuse what is the same. We will do this for the expected behaviour, then for the comparison code.

**Reusing the Expected behaviour**

To specify the expected behaviour once only change your original tests as follows:

assert( addExpected( 2, 4 ) == add( 2, 4 ) )

assert( addExpected( -2, -4 ) == add( -2, -4 ) )

function addExpected( a, b ) { return a + b }

Notice the two changes

"Due to customer requirements, the add command will now round to the nearest 10 instead"

- on the first two lines, the expected values are not hard coded any more, in fact the expected behaviour is not represented at all
- the third line represents the expected behaviour

**Our original change request comes in!**

"Due to customer requirements, the add command will now round to the nearest 10 instead"

I add the round function on the third line:

assert( addExpected( 2, 4 ) == add( 2, 4 ) )

assert( addExpected( -2, -4 ) == add( -2, -4 ) )

integer addExpected( a, b ) { return round(a + b, 10) }

Imagine a thousand different tests for add - the change is still the same size.

**Reusing the Comparison logic**

To specify the comparison logic only once, modify your tests as follows:

assert( addResultCheck( addExpected( 2, 4 ) , add( 2, 4 )) )

assert( addResultCheck( addExpected( -2, -4 ), add( -2, -4 )) )

function addExpected( a, b ) { return round(a + b, 10) }

function addResultCheck( expected, actual ) { return expected == actual }

"Due to a customer request, the add command will also return the amount the value was rounded by"

Please leave a comment to say whether you enjoyed my article. Whether you would like to hear more on this topic, or you would prefer to hear about other topics just let me know!

The new code is longer, yet it is more maintainable and has a clear separation.

- The first two lines ONLY describe the scenarios - try adding 2 and 4, and try adding -2 and -4.
- The third line ONLY describes the expected behaviour
- The final line ONLY describes the comparison logic

**Our second change request comes in!**

"Due to a customer request, the add command will also return the amount the value was rounded by"

I update the expected result to include the rounding amount, and the comparison code to check the rounding amount.

assert( addResultCheck( addExpected( 2, 4 ) , add( 2, 4 )) )

assert( addResultCheck( addExpected( -2, -4 ), add( -2, -4 )) )

function addExpected( a, b ) { total = a + b; return [ round(total, 10), remainder(total, 10) ] }

function addResultCheck( expected, actual ) { return expected.sum == actual.sum && expected.rounding == actual.rounding }

You can see that the effort to contain product changes is no longer related to the number of tests, purely to the size of the change. There is no risk of accidentally forgetting to update a test.

**Feedback**

Please leave a comment to say whether you enjoyed my article. Whether you would like to hear more on this topic, or you would prefer to hear about other topics just let me know!

As always, I only speak for myself not for IBM.

In part three, learn how to separate out the logic about the operation, and completely factor the test into components!

## Comments (0)

There are no comments to displayAdd a Comment