5

Is there a good way to unit test a function or a class using OpenGL commands?

For c++, I know I could make the class a template and pass a class doing direct opengl calls :

namespace myNamespace
{
struct RealOpenglCall
{
  static inline void glVertex2fv( const GLfloat * v)
  { ::glVertex2fv( v ); }
};

template< typename T >
class SomeRendering
{
  public:
    SomeRendering() : v()
    {
      // set v
    }
    void Draw()
    {
      T::glVertex2fv(v);
    }
    GLfloat v[4];
};

}

In C and c++, I could pass function pointers to functions calling opengl functions (then for unit testing passing pointers to mock functions).

I could also link with different library (instead of opengl), but that sounds like a big complication.

So, what are other techniques to unit test code calling opengl functions?

BЈовић
  • 62,405
  • 41
  • 173
  • 273

1 Answers1

5

Here is a nice trick i learned a while back. You can use regular old #defines to let you mock all kinds of API functions:

#ifdef _test_
#define glVertex3f(x,y,z)  (mockGlVertex3f((x),(y),(z)))
...
#endif

With a configured preprocessor. There is no need to change your drawing-functions at all. Further: you can implement mockGlVertex3f in such a way that it e.g. checks the arguments or counts the number of calls to it which can then later be checked.

Bernd Elkemann
  • 23,242
  • 4
  • 37
  • 66
  • You could use unit-testing data and have the mocking functions dump that data for comparison, passing the unit test if it matches the expected output. – datenwolf Mar 11 '11 at 09:38
  • @datenwolf Then it is not an unit test, since it would need to read disk and access real data. That slows down unit testing – BЈовић Mar 11 '11 at 13:43
  • @VJo: How do you distinct between real and testing data? And results can be dumped into memory, too. – datenwolf Mar 11 '11 at 13:49
  • @datenwolf: `"how do you distinct between real and testing data?"`: The caller decides this by defining `_test_` and then calls the function supplying any data he likes. The data will be handled by e.g. `mockGlVertex3f()` which can do with it whatever you want it to do. – Bernd Elkemann Mar 11 '11 at 13:55
  • Exactly. And no need to load anything. you can (for example) set some simple int counter which counts number of calls to this function and print to std::stringstream – BЈовић Mar 11 '11 at 13:59
  • @eznme: I meant this in a different way: Test data is just this: Data, like any data. The whole point of a unit test is, that it shall process the test data as if it were real data. This was a reaction to @VJo's "Then it is not an unit test". The whole point is, that the testee is unaware of the test condition. – datenwolf Mar 11 '11 at 14:18
  • @datenwolf Ah yes interesting – Bernd Elkemann Mar 11 '11 at 14:48