作爲我單元測試的一部分,我希望確保代碼覆蓋測試。目的是在代碼的某處放置類似REQUIRE_TEST
的宏,並檢查是否調用了所有這些宏。查找未執行的C++代碼行
void foo(bool b) {
if (b) {
REQUIRE_TEST
...
} else {
REQUIRE_TEST
...
}
}
void main() {
foo(true);
output_all_missed_REQUIRE_macros();
}
理想情況下,輸出將包括宏的源文件和行。
我最初的想法是讓宏創建,將自己註冊在一些地圖,後來檢查是否所有這些被稱爲
#define REQUIRE_TEST \
do { \
static ___RequiredTest requiredTest(__func__, __FILE__, __LINE__);\
(void)requiredTest;\
___RequiredTest::increaseCounter(__func__, __FILE__, __LINE__);\
} while(false)
但靜態對象只創建靜態對象時,代碼被稱爲第一次。所以地圖只包含在下一行中計算的函數 - 找不到REQUIRE_TEST宏。在這種情況下,__attribute__((used))
被忽略。
gcc的有一個很好的屬性__attribute__((constructor))
,但顯然在這裏放置時選擇忽略它(以下代碼,而不是靜態對象)
struct teststruct { \
__attribute__((constructor)) static void bla() {\
___RequiredTest::register(__func__, __FILE__, __LINE__); \
} \
};\
以及用於
[]() __attribute__((constructor)) { \
___RequiredTest::register(__func__, __FILE__, __LINE__); \
};\
唯一我現在可以想到的是a)手動(或通過腳本)分析常規編譯之外的代碼(uargh)或b)使用宏來計算宏 - 但之後我不知道哪些特定的REQUIRE_TEST宏是不是calle d ...(如果別人決定使用__COUNTER__
宏以及一切休息...)
是否有解決這個問題的任何解決方案,得體?我錯過了什麼?它 會很高興有一個宏附加當前行和文件 所以一些預處理器變量,只要它被調用 - 但這不是 可能,對吧?有沒有其他的方法可以在
main()
之前執行的 之類的東西可以在函數體內完成?
研究編譯器的警告和命令行選項。許多編譯器都有能力識別「死代碼」。 –
TL; DR;爲什麼不使用像''gcov'](https://gcc.gnu.org/onlinedocs/gcc/Gcov.html)這樣的覆蓋率分析代碼注入並分析結果,例如使用['lcov'](http://ltp.sourceforge.net/coverage/lcov.php)?如果_dead code_沒有從您的測試場景中執行,那麼這可能不一定真正批准。一個靜態代碼分析工具可能會更好地找到這種死的東西。 –
@πάνταῥεῖ'gcov'非常詳細 - 但也代碼部分我不太在意。像「REQUIRE_TEST」這樣的標記可以讓我指定我關心的部分。它也將成爲我的圖書館所有人的另一個依賴 - 並且它感覺像C++幾乎可以做我想做的事情......如果我的任何嘗試工作,我會擁有我想要的一切。也許像'gcov'這樣的結果將是唯一的解決方案 - 但我想知道,我所嘗試的是不可能的,然後再「放棄」並添加另一個依賴項... – example