开发者

White-box testing - friends or preprocessor?

Imagine we have a class like this:

class Testee
{
public:
   void Func()
private:
   void auxFunc()
};

and we want to do white-box unit-testing on it. Which do you think is a better approach? To declare the tester class a friend of the testee class? Or use the preprocessor like this:

  class Te开发者_开发百科stee
    {
    public:
       void Func()
#ifndef UNITTEST_SYMBOL
    private:
#elif
    public:
#endif
       void auxFunc()
    };

and later in the testing file

#define UNITTEST_SYMBOL
#include "Testee.h"
#undef UNITTEST_SYMBOL

So, again, which do you think is a better approach? Or maybe you could suggest another approach.


How about:

#ifndef UNITTEST_SYMBOL
#define semiprivate private 
#else
#define semiprivate public
#endif

and declare your class like:

  class Testee
    {
    public:
       void Func()
    semiprivate:
       void auxFunc()
    };

or even, if you're daring enough, do #define private public when testing.


In the unit test file. You could try

#define private public
#include "Testee.h"

This is what I do, it means that there isn't anything related to unit testing within the header file. I find this very useful as I find it hard to follow when there are lots of #ifdef within my code.

I then have all my other header files before the #define


Using the friend method, the declaration would depend on the name of the test class, so if you ever change it's name the declaration has to be changed as well. Moreover I use Unittest++ so the actual test calss name is formed by a macro.

The method with the define is less hassle then. Also, I'd just put the define as a global compiler option instead of the way you show, for example

gcc -DUNIT_TESTING_ON

#ifdef UNIT_TESTING_ON
  public: //or protected maybe
#else
  private:
#endif

Anyone reading this would also see what the purpose is, this is more clear than having to look up the definition of the friend to see why exactly you made it a friend.


Below is the way that people follow for white box testing,

#define private friend cTestDriver; private
#define protected friend cTestDriver; protected
//included all your class header from which you like to access
//the private/protected method
#include Testee.h"
#undef private
#undef protected

The class cTestDriver will have wrappers/setters/getters to access all the private and protected members.

Also you have to be sensible about the order of headers files.

For ex:

File1.h

#include "Testee.h"
--
--
--

file TestDriver.h

#include File1.h
#define private friend cTestDriver; private
#define protected friend cTestDriver; protected
//included all your class header from which you like to access
//the private/protected method
#include Testee.h"
#undef private
#undef protected

In the above case the Testee.h will be opened while we open File1.h. So the macros wont be effective here.

Note : You may get warning about multiple declaration of friend.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜