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


Let's say you have some code like this (in a made-up langague, since it does not matter for this question):

constant float PI = 3.14;  float getPi()   {      return PI;  }  

Would you test it like this:

testPiIs3point14()  {     // Test using literal in test case     AssertEquals( getPi(), 3.14 );  }  

Or like this:

testPiIs3Point14()  {     // Test using constant from implementation in test case     AssertEquals( getPi(), PI );  }  

In other words, do you use constants from your system under test in your test cases? Or is this considered an implementation detail?


The two tests serve different purposes.

The first one ensures that getPi() will always return 3.14. It covers both the constant and the function and will fail if ever someone find 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.

While the second form 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.


I think there are two distinct cases here:

  1. If you are testing a constant that is critical to the result of a calculation, as in your example, I think it's better to use an independent test rather than re-using the same constant from the code you are trying to test. Instead of testing the constant value directly, I would test (for example) the function CalculateAreaOfCircle(), which would verify that the Area formula is correct and at the same time verify the value of PI.

  2. I think it makes sense to re-use enumerations and other constants that do not directly affect the outcome of critical parts of the code.


If you really have both exposed as part of the public interface, it would be two tests:

testPI() {     AssertEquals(PI, 3.14);  }    test_getPi() {     AssertEquals(getPi(), 3.14);  }  

However, if PI is an implementation detail, and getPi is the public means to retrieve the value, then you would only write test_getPi, as above, and PI should be private with no testPI unit test. This latter case is probably more like what you should do.

I guess you could have a third test like this:

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

This says that these two pieces of code should always evaluate to the same value, whatever that value is. If that's how your logic is supposed to work, that's how you'd test it, but more likely you shouldn't be having two identical means of doing the same thing in the first place.

Note that this last test does not say that getPi is expected to return 3.14, only that the two pieces of code should have the same value, without any indication of what that value is. To assert that the value of one or the other should be some specific value, use one of the first two tests.


Definitely the second form, the purpose of the constant is to not introduce a "magic number". Now, in unit tests, you tend to use magic numbers quite a bit and that's OK.

In this case, you introduced a constant AND used a magic number. I would either use the constant everywhere or not use it at all.


I use the first form - even though it duplicates the value (twice only), it is more readable.

[Test]  public void GetPIReturns3_14()  {    Assert.AreEqual(3.14, testSubject.GetPI());  }  

The duplication is necessary because if you reuse the constant as in the second test, you are not really testing anything. In effect, you're testing "Is Constant == Constant?". This test would never fail. e.g. if I change PI to be 1010.1010, the second test wouldn't fail.

Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Next Post »