Unit Testing

Unit Testing

Q: How many test cases are there for the following Java function?

double divide(final double x, final double y) {
    return x / y;
}

A1: None. This is the sane and sensible answer and illustrates why “percentage of code covered” is not a valid software quality metric. The divide(double, double) function does not need a unit test because all you would be testing is the IEEE floating point implementation by the compiler and run-time system, not anything about your own code’s logic.

A2: Thirteen. This is the full-bore, ideolgically pure TDD (Test Driven Development) answer. According to the IEEE floating specification mandated for Java implementations, all of the following correspond to legitimate, distinct and well-defined numeric values (including, ironically, the “numeric” value meaning “Not a Number”).

  1. $$ \forall x y (((x > 0) \wedge (y > 0)) \rightarrow ({\frac x y} > 0)) $$

  2. $$ \forall x y (((x < 0) \wedge (y < 0)) \rightarrow ({\frac x y} > 0)) $$

  3. $$ \forall x y (((x < 0) \wedge (y > 0)) \rightarrow ({\frac x y} < 0)) $$

  4. $$ \forall x y (((x > 0) \wedge (y < 0)) \rightarrow ({\frac x y} < 0)) $$

  5. $$ \forall x y (((x = 0) \wedge (y > 0)) \rightarrow ({\frac x y} = 0)) $$

  6. $$ \forall x y (((x = -0) \wedge (y > 0)) \rightarrow ({\frac x y} = -0)) $$

  7. $$ \forall x y (((x = 0) \wedge (y < 0)) \rightarrow ({\frac x y} = -0)) $$

  8. $$ \forall x y (((x = -0) \wedge (y < 0)) \rightarrow ({\frac x y} = 0)) $$

  9. $$ \forall x y (((x > 0) \wedge (y = 0)) \rightarrow ({\frac x y} = \infty)) $$

  10. $$ \forall x y (((x < 0) \wedge (y = 0)) \rightarrow ({\frac x y} = - \infty)) $$

  11. $$ \forall x y (((x > 0) \wedge (y = -0)) \rightarrow ({\frac x y} = - \infty)) $$

  12. $$ \forall x y (((x < 0) \wedge (y = -0)) \rightarrow ({\frac x y} = \infty)) $$

  13. $$ \forall x y (((x = \pm 0) \wedge (y = \pm 0)) \rightarrow ({\frac x y} = \text{NaN})) $$

However, note that having a unit test for any one of the thirteen distinct test cases would achieve 100% code coverage. You are very unlikely to find a programmer in the real world who would bother with all thirteen when one would be sufficient to satisfy any “percentage of code covered” checks.

This is another reason that “percentage of code covered” as a quality check is an anti-pattern. It simulataneously encourages bad behavior on the part of developers and a false sense of security about the actual quality of your code. If you do go down this route, you actually need to mandate a far greater than 100% code coverage and that is nearly impossible to check for in any automated fashion, laying aside the schedule and budget concerns that arise from a development team that spends nearly all its time designing, implementing and debugging unit tests compared to the time spent on the features being tested.

Q: So does this mean unit testing is a waste of time?

A: Obviously not. It is just that “percentage of code covered” is only useful as a tool for developers to know where to look in their code for areas that might need attention rather than as a metric to be enforced by decree or embraced out of theoretical fervor.