Do you use constants from the implementation in your test cases?

The two tests verify/assert different purposes.

  • The first one (using literal in the test case)
    Ensures that getPi() will always return 3.14.
    It covers both the constant and the function and will fail if ever someone finds the PI value used in the software is not accurate enough and replace it with, say 3.14159.
    This can be good or bad, depending on the context.

  • The second one (reuse the implementation code)
    only covers the function.
    It will not fail if someone changes the constant;
    It will only fail if the function is modified to return another constant (with a different value).

Choosing between the two depends on the objective of the test.

  • Use a literal if the constant must never change.
  • Use the constant to pin down the behavior of the function: return a constant - whatever its value. In the second case, the test may be needless.

I was looking for information on this same topic. My conclusion so far is that you should not use literals, but you should also make sure the constant is what you expect it to be.

If you used literals in 10 different unit tests and the value changed for any reason, then you'd have to change the value in all 10 literals. You could or example need to add more precision to PI.

The best alternative IMHO is to implement a unit test to check the constant's value to be what you expect, and then use the constant freely in your other tests.

Something along the lines of implementing these two tests:

testPiIs3point14()
{
   AssertEquals( PI, 3.14 );
}

testGetPiReturnsPi()
{
   AssertEquals( getPi(), PI );
}

PS: While checking the value may not be so important for all constants, it could be very important for some. One example I can think of is constants that contain URLs or similar values.


I think this is the question about coupling between the tests and the production code. When I first started TDD I thought that having the constant in the tests makes the tests more thorough. However, now I think it just causes tighter coupling between the tests and the implementation. Does it make it more safe if you copy and paste the constant to the test? Not really. It just makes it more painful to change the constant, especially if its copy-pasted to multiple tests. These tests don't test if it is the right constant, they just test that this constant is returned from the method, so now I would definitely go for test number two.