2012-12-13 56 views
0

我有一個用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的回覆中我明白這不是問題。

我應該如何編寫這樣的代碼測試?

+1

您是否收到錯誤? –

+1

所以你想告訴我們,在使用unittest ++時,你沒有告訴我們如何使用它,你犯了什麼錯誤? – PlasmaHH

+0

即使在編譯器啓動之前,宏也會被擴展,更不用說單元測試運行時 – 2012-12-13 16:04:10

回答

0

我建議看看代碼是實際生成的,因爲你有一個編譯問題,這聽起來像是宏沒有生成你期待它的代碼。如果您使用的是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); 
    } 
} 
+0

另外,您的單元測試中的PROPERTY_SWITCHPOINT沒有按照您的想法執行。宏擴展到位,所以它只是將類內部轉儲到您的TEST(SwitchPointtest1)命名空間 – jeremy

+0

這是一個好主意。我找不到任何雙重的私人或公共關鍵字,但它確實證實了Aleguna提到的內容。 – Nico

+0

您包括ClassName.h,因此您應該有權訪問該對象而不嘗試重新添加該宏。 – jeremy

0

嘛錯誤是很明顯的

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

不能使用private:public:(其中包含在您的宏)的關鍵字在一個函數體中。

+0

我遵循了傑里米的建議,你是對的。有沒有一種方法可以將測試中的宏調用掉? – Nico

+0

由於代碼已經生成,我認爲你可以刪除宏行:PROPERTY_SWITCHPOINT(SwitchpointObject) – jeremy