Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 341
WW. Avatar asked Jul 29 '10 06:07

WW.


People also ask

Should I use constants in unit tests?

Every developer wants to promote code reuse. Generally, reuse is a good thing. It makes for more maintainable and more correct code.

Which of the following is correct about a unit test case?

Q 10 - Which of the following is correct about a Unit Test Case? A - A Unit Test Case is a part of code which ensures that the another part of code (method) works as expected.

What should you unit test?

Good unit tests should be reproducible and independent from external factors such as the environment or running order. Fast. Developers write unit tests so they can repeatedly run them and check that no bugs have been introduced.


2 Answers

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.
like image 181
philant Avatar answered Nov 10 '22 10:11

philant


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.

like image 44
diegoreymendez Avatar answered Nov 10 '22 10:11

diegoreymendez