【问题标题】:Unit testing methods created by a macro由宏创建的单元测试方法
【发布时间】:2012-12-01 12:34:09
【问题描述】:

我有一个用 C++ 编写的程序,为了确保在进行更改时不会破坏任何内容,我想添加单元测试。

在程序中,我们使用宏来创建某些经常使用的对象。这看起来像:

#define PROPERTY_SWITCHPOINT(var) \
private: \
   comp::SwitchPoint* m##var; \
public: \
   void set##var(bool val, unsigned short switchIdx = 0) \
   {\
      if(m##var)  m##var->setValue(val,switchIdx); \
   }\
   bool get##var() \
   {\
      return (NULL == m##var ? false : m##var->getValue()); \
   }\
   comp::SwitchPoint* get##var##Ptr() \
   {\
      return m##var; \
   }

在包含我们调用宏的开关点的类的标题中

class Classname
{
    private:
        PROPERTY_SWITCHPOINT(SwitchpointObject)
}

在包含开关点的类的构造函数中,我们接着做:

Classname::Classname()
{
    mSwitchpointObject = CreateSwitchpoint("Switchpoint name", 2);
}

comp::SwitchPoint* Classname::CreateSwitchpoint(const std::string& name, unsigned short numberOfSwitches = 1)
{
    comp::SwitchPoint* sp = new comp::SwitchPoint(name, true, numberOfSwitches);
    return sp;
}

现在我们可以使用mSwitchpointObject->getValue() 来获取这个对象的值。所有这些都有效,但我无法为它创建单元测试,我使用的是 unittest++ 框架。 我用这个测试试过了:

#include "UnitTest++.h"
#include "Classname.h"

namespace
{
    TEST(SwitchpointTest1)
    {
        PROPERTY_SWITCHPOINT(SwitchpointObject)
        mSwitchpointTestVariabele           = CreateSwitchpoint("test switchpoint", 2);
        CHECK_EQUAL(mSwitchpointTestVariabele->getValue(), true);
        //mSwitchpointTestVariabele->setValue(false, 0);
        //CHECK_EQUAL(mSwitchpointTestVariabele->getValue(), false);
        //mSwitchpointTestVariabele->setValue(false, 1);
        //CHECK_EQUAL(mSwitchpointTestVariabele->getValue(), false);
        //mSwitchpointTestVariabele->setValue(true, 0);
        //CHECK_EQUAL(mSwitchpointTestVariabele->getValue(), false);
        //mSwitchpointTestVariabele->setValue(true, 1);
        //CHECK_EQUAL(mSwitchpointTestVariabele->getValue(), true);
    }
}

但这给了我编译器错误:

|  |In member function 'virtual void<unnamed>::TestSwitchpointTest1::RunImpl() const':|
| 9|error: expected primary-expression before 'private'|
| 9|error: expected ';' before 'private'|
| 9|error: expected primary-expression before 'public'|
| 9|error: expected ';' before 'public'|
| 9|error: a function-definition is not allowed here before '{' token|
| 9|error: a function-definition is not allowed here before '{' token|
|10|error: 'mSwitchpointTestVariabele' was not declared in this scope|
|10|error: 'CreateSwitchpoint' was not declared in this scope|
|  |=== Build finished: 8 errors, 0 warnings ===|

我猜问题是宏创建了需要测试的代码的一部分,并且在创建这部分之前执行了单元测试,但是从 Aleguna 的回复中我知道这不是问题所在。

我应该如何为这样的代码编写测试?

【问题讨论】:

  • 所以你想告诉我们你在使用 unittest++ 时犯了什么错误而不告诉我们你是如何使用它的?
  • 宏甚至在编译器启动之前就已经扩展,更不用说单元测试运行时了
  • 我刚刚添加了我得到的错误,一开始忘记了。
  • afaics 该宏被设计为仅在类定义中使用...

标签: c++ unit-testing macros unittest++


【解决方案1】:

我建议查看实际生成的代码,因为您有编译问题,听起来宏没有生成您期望的代码。如果您使用的是 windows/VS,您可以使用“cl.exe /E”或在 g++/gcc 中您可以使用“gcc -E source.cpp”来运行预处理器并生成将被编译的 c++ 文件。

只有在成功编译代码后才能运行单元测试(并且可以像对任何其他代码进行单元测试一样进行测试)。

您的单元测试代码正在扩展为:

 #include "UnitTest++.h"
    #include "Classname.h"

    namespace
    {
        TEST(SwitchpointTest1)
        {
                private:
       comp::SwitchPoint* mSwitchpointObject;
    public:
       void setSwitchpointObject(bool val, unsigned short switchIdx = 0)
           {
              if(mSwitchpointObject)  mSwitchpointObject->setValue(val,switchIdx);
           }
       bool getSwitchpointObject()
       {
          return (NULL == mSwitchpointObject ? false : mSwitchpointObject->getValue()); 
       }
       comp::SwitchPoint* getSwitchpointObject##Ptr() 
       {
          return mSwitchpointObject; 
       }


 mSwitchpointTestVariabele           = CreateSwitchpoint("test switchpoint", 2);
        CHECK_EQUAL(mSwitchpointTestVariabele->getValue(), true);
        //mSwitchpointTestVariabele->setValue(false, 0);
        //CHECK_EQUAL(mSwitchpointTestVariabele->getValue(), false);
        //mSwitchpointTestVariabele->setValue(false, 1);
        //CHECK_EQUAL(mSwitchpointTestVariabele->getValue(), false);
        //mSwitchpointTestVariabele->setValue(true, 0);
        //CHECK_EQUAL(mSwitchpointTestVariabele->getValue(), false);
        //mSwitchpointTestVariabele->setValue(true, 1);
        //CHECK_EQUAL(mSwitchpointTestVariabele->getValue(), true);
    }
}

【讨论】:

  • 另外,您在单元测试中的 PROPERTY_SWITCHPOINT 并没有按照您认为的那样做。宏就地展开,因此它只是将类内部内容转储到您的 TEST(SwitchPointtest1) 命名空间中
  • 这是个好主意。我找不到任何双重私有或公共关键字,但它确实证实了 Aleguna 提到的内容。
  • 您包含 ClassName.h,因此您应该可以访问该对象而无需尝试重​​新添加宏。
【解决方案2】:

这个错误很明显

In member function 'virtual void<unnamed>::TestSwitchpointTest1::RunImpl() const':

您不能在函数体中使用 private:public:(包含在您的宏中)关键字。

【讨论】:

  • 我听从了 Jeremy 的建议,你是对的。有没有办法从测试中调用宏?
  • 由于代码已经生成,我认为您可以删除该宏行:PROPERTY_SWITCHPOINT(SwitchpointObject)
猜你喜欢
  • 2010-12-16
  • 1970-01-01
  • 2011-08-23
  • 2019-06-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-13
相关资源
最近更新 更多