2009-07-13 167 views
6

如何在單元測試中測試想要的編譯器錯誤?編譯器錯誤的單元測試

考慮代碼:

class ErrorTest 
{ 
    OtherClass& read_write() { 
     return other; 
    } 

    const OtherClass& read_only() const { 
     return other; 
    } 

    private: 
     OtherClass other; 
}; 

我如何測試READ_ONLY()分配?這是非常重要的,應該堅決檢查,以正確生成編譯器錯誤:

ErrorTest test; 
OtherClass other = test.read_only(); 
test.read_write() = other.modify(); 
test.read_only() = other.modify(); /* This should error */ 
+0

好問題。我以前也想過。雖然從未真正找到好答案。當然你可以編寫一個腳本來嘗試編譯文件,並驗證錯誤代碼或其他東西,但這不是一個優雅的解決方案 – jalf 2009-07-13 22:29:54

回答

1

我想主要的現在的問題是,你測試你的代碼或在這一點上,編譯器?

測試編譯器並不一定是壞事......我已經讓編譯器升級屏蔽了過去的錯誤,所以最好確保您得到您期望的相同安全檢查。

但是,你必須做很多工作。您的單元測試必須產生編譯器,捕獲它的輸出,並在正確的行上解析它以獲取正確的錯誤語句。這不是微不足道的,可以說是不值得的。

一個稍微簡單的方法可能是保持一個錯誤代碼的目錄,並讓腳本每次編譯一個文件。在那裏有一個'#ifdef MAKEFAIL'標誌,打開應該失敗的確切條件。確保編譯器在您未設置該標誌時返回0,而在您設置時不返回零。這假定編譯器在失敗時返回非零值......我不知道MSVC是否遵循該規則。

爲了解決可移植性問題,我將拋出第三個選項是autoconf。設置起來可能很痛苦,但其目的之一就是在編譯之前確保你有一個健全的開發環境。你可以在其中添加一個像這樣的測試,它可以處理查找編譯器並嘗試它。

+6

他正在測試他的代碼是否是const正確的。所以我認爲他仍然在測試他的代碼,只不過他正在測試它的屬性,而這些屬性在編譯時纔是明顯的。 – 2009-07-13 22:21:42

+0

我讀到,因爲他試圖確保編譯器生成警告,而不是沒有警告。有一個單元測試告訴你編譯器有抱怨,但似乎有點多餘,但是如果你有一個很好的單元測試輸出解析器,它也許是有意義的。 – 2009-07-13 22:30:15

1

這看起來有點像當你在一臺* nix機器上從源碼構建「./configure」時發生的自動檢測。 autoconf腳本構建小程序並嘗試編譯它們以確定編譯器提供和支持的內容。

重複使用任何一種方法可能不切實際,但您可能需要相同的模型。每個測試都有自己的文件或一組文件,以及一個單獨的項目文件/ make target/etc。然後,您的測試腳本將嘗試製作每個測試用例,並通過grep或通過比較輸出到與測試案例一起存儲的基線輸出。

0

編譯器和平臺的有效測試將針對運行時的行爲變化。我經常這樣做,重現生產代碼中存在的一小部分行爲,並檢查行爲是否如預期。

但是對於這種情況,你真正想要的是一個靜態分析工具,它檢查以確保開發人員編寫的代碼遵循諸如此類的約定。這當然是一個有效的構建工具。但是,搜索靜態分析工具以查找您在此處指定的內容可能很困難。我首先從維基百科文章List of tools for static code analysis開始,在C/C++部分。

請注意,您編寫的代碼不是「錯誤」,它只是您的約定。這是一個非常好的約定,但編譯器不會也不應該約束你。靜態分析工具也不應該。因此,您需要找到一個允許您配置允許和不允許配置的配置。