George Edwards
George Edwards

Reputation: 9229

Unit Testing Mathematical C++ routine

What is the best practice for testing a mathematical routine. I am using the routine below and trying to write a unit test for it (I am just learning about unit testing). I am using the Visual Studio built in framework.

Whenever I start trying to use the Assert command to check actual values against known right answers, I end up writing the same code I am testing to get a comparison, which obviously doesn't prove anything at all. What is the conventional way to deal with this?

int averageGradient(int x1, int x2, float m) {
    int i = 0, y1 = 0, y2 = 0;
    while (y1 != 0 && y2 != 0) { //if both y values haven't been solved then keep trying
        if (x1 >= graph[0][i] && x1 < graph[1][i] && y1 == 0) { // if x1 lies in the first straight line segment
            y1 = (graph[2][i] * x1) + graph[3][i];              // then calculate it's y value (y1)
        }
        else { i++; }                                //otherwise incriment i to check the next straight line segment
        if (x2 >= graph[0][i] && x2 < graph[1][i]) {  //try the same thing for x2
            y2 = (graph[2][i] * x2) + graph[3][i];    //calculate its y value (y2)
        }
        else { i++; }
    }
    m = (y2 - y1) / (x2 - x1);
    return m;
};

Upvotes: 0

Views: 615

Answers (3)

Roberto
Roberto

Reputation: 2185

You precalculate your expected result (may be with a math app, or tabulated data) and put that "hard coded" value in your Assert:

AssertEqual(calculatePiFirst6Decimals(), 3.141519);

The way is to test known values/results (else there is no point testing something, it cannot be verified). Then one should test known edge cases as well (for example when arguments take extreme values or need special care)

Upvotes: 1

Peti29
Peti29

Reputation: 237

I don't understand.

var a = knownParameter1;
var b = knownParameter2;
var c = knownParameter3;
var ret = knownReturnValue;
Assert(ret == averageGradient(a, b, c));

You're not writing the same code again...

Upvotes: 0

John Zwinck
John Zwinck

Reputation: 249153

  1. Make your unit tests read their input and expected output from text files. This makes it easier to generate and diff the values rather than the mechanism.
  2. Explicitly test all the boundaries, such as INT_MIN, INT_MIN+1, -1, 0, 1, INT_MAX-1, INT_MAX. For floating point, try the inputs INF and NAN. If nothing else your tests can help you document what your functions do in the presence of these values.
  3. If you are convinced your algorithm is correct now, write a large set of random inputs, generate the outputs, spot-check them for sanity, and check those in. This will alert you if the results change in the future. This is "black box" testing, meaning you don't explicitly know what the "correct" values are, but if you believe the algorithm is correct today, you want to make sure it doesn't change.

Upvotes: 3

Related Questions