6

I am currently trying to write a unit test of my own. The unit test I am writing is mainly for linear algebra (I know there are great package out there but I want to use my own for my project). My current linear algebra consist of my_vector.hpp/cpp (3d) and my_matrix.h/cpp.

So I am currently writing a test_vector.cpp and test_matrix.cpp which will test the features of my_vector and my_matrix.

In regards to testing vector class, inside test_vector.cpp I test my_vector's add, subtract, divide, dotproduct etc features.

How I do it is :

// test_vector.cpp
void test_add(){

    my_vector a(2.0, 1.1, 2.1);
    my_vector b(2.1, 2.0, 1.1);

    // manually computed by adding a and b by hand
    // 
    my_vector expected(4.1, 3.1, 3.2);


    my_vector c = a + b;

    assert(c.x == expected.x);
    assert(c.y == expected.y);
    assert(c.z == expected.z);
}

void test_sub(){

    .....
}

int main(){
    test_add();
    test_sub();
    ....
return 0;
}  

I do similar for test_matrix.cpp as well.

In my_vector expected(4.1, 3.1, 3.2); I firstly manually added 2.0, 1.1, 2.1 of a and 2.1, 2.0, 1.1 of b and then compared to the value computed after using c = a + b. Do you think this is a proper way to do unit testing. I find it little cumbersome since I have to do the computation by hand for other complex test like rotation, cross product etc also. This kind of gives a feeling that I am doing something wrong.

Am I doing something wrong? Please let me know, I am open for any suggestions.

5

This is quite a common way of doing it, and I wouldn't describe it as wrong. There are alternatives, though -- for instance, you could find another calculation that you can apply to the results which should be simpler to calculate and would show they're correct. For addition, that's probably not feasible, but for rotation about 90 degrees, you could consider applying a dot product and checking its zero, and checking that the magnitude is correct, and that would give you a very good idea that the implementation is correct (assuming your implementation of these other, simpler operations is already known to be correct).

You can take this a step further and run such calculations on random data. Doing this on a large number of items can give you confidence that you've caught all of the edge cases in an algorithm.

One further piece of advice: I notice you're not using a unit testing framework. While this is possible, I would strongly suggest using a framework as they provide much better feedback when things go wrong. For C++, I tend to use Catch but there are many other alternatives too.

2

Using a unit testing framework is ver (very) sound advice, as Pariata Breatta pointed out. It makes testing much easier, and is supported by many IDEs.

Consider putting the equality test in your vector class itself, making it much easier to reuse it in unit tests later - and it will most probably come very handy sooner or later anyway. Oh, write a non-recursive unit test for that as well, of course. Checking all components is usually the way to go, and using your new method it will only have need assertion for that. Just comparing sums introduces new possible points of failures (think about permutation or numerical errors).

You might want to supply an "about equal"-check supporting some epsilon around your values to allow for numeric inaccuracy effects, as working with floating point numbers might just not end up the way you expect them to be.

  • When you say "Consider putting the equality test in your vector class itself" do you mean to write operator== for my_vector class? and also what do you really mean when you say "write a non-recursive unit test for that as well" .. and also I do actually have epsilon thing already implemented for decimal assertion:) – solti Oct 20 '16 at 16:13
1

You're doing it right. The only alternative I can see to the manual approach would be to use a trusted third party library to run your calculations, then have the test suite compare your calculations with the library's.

Of course, it would be redundant to implement the functionality of a library you already have access to. I imagine you would only do this if the library cannot, for whatever reason, be used when you go live and you are forced to implement your own.

By the way, shouldn't the expected result be (4.1, 3.1, 3.2) ?

  • thank you for the response and thank you for correcting my typo :) – solti Oct 20 '16 at 17:06
1

Use Google Test framework. For mocking there's also Google Mock framework. Both are meant to be used with C++.

  • The question isn't a software recommendation one, so this isn't a good answer. – Periata Breatta Oct 21 '16 at 14:26
  • 6
    OP asks the following: 'Am I doing something wrong? Please let me know, I am open for any suggestions'. What he's doing wrong is NOT using a testing framework, and I suggested one of the best ones out there. – Eternal21 Oct 21 '16 at 16:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.