常見 C++ 單元測試框架對比
| 框架 | 特點 |
| CppUnit | xUnit 風格,熟悉 JUnit/NUnit 者上手快 |
| CxxTest | 需預處理器,依賴 Perl/Python |
| Boost.Test | 功能強大,自動/手動註冊,Boost 庫出品,質量可靠 |
| Google Test | Google 開源,大型項目驗證,語法現代 |
快速上手:自動註冊模式
#define BOOST_TEST_MODULE example
#include <boost/test/unit_test.hpp>
int add(int i, int j); // 被測函數
BOOST_AUTO_TEST_SUITE(minimal_test)
BOOST_AUTO_TEST_CASE(my_test) {
BOOST_CHECK(add(2, 2) == 5); // 失敗,記錄錯誤繼續
BOOST_REQUIRE(add(2, 2) == 4); // 失敗則拋異常,停止當前用例
if (add(2, 2) != 4) BOOST_ERROR("oops!");
if (add(2, 2) != 4) BOOST_FAIL("oops!"); // 拋異常停止
if (add(2, 2) != 4) throw "oops!"; // 同 BOOST_FAIL
BOOST_CHECK_MESSAGE(add(2,2)==4, "add result: " << add(2,2));
BOOST_CHECK_EQUAL(add(2, 2), 4); // 專用相等檢查,輸出更友好
}
BOOST_AUTO_TEST_SUITE_END()
關鍵宏說明
BOOST_TEST_MODULE:定義測試模塊名,**整個測試程序只能定義一次**
BOOST_AUTO_TEST_SUITE(name):創建測試套件,自動加入主套件
BOOST_AUTO_TEST_CASE(name):創建測試用例,自動加入當前套件
- 斷言宏:
CHECK(記錄繼續) vs REQUIRE(致命停止);ERROR/FAIL 自定義消息
參數化測試:單用例多數據
#include <boost/test/included/unit_test.hpp>
#include <boost/test/parameterized_test.hpp>
using namespace boost::unit_test;
void free_test_function(int i) {
BOOST_CHECK(i < 4);
}
test_suite* init_unit_test_suite(int argc, char* argv[]) {
int params[] = {1, 2, 3, 4, 5};
framework::master_test_suite().add(
BOOST_PARAM_TEST_CASE(&free_test_function, params, params+5)
);
return 0;
}
將用參數 1~5 分別運行 5 次測試。BOOST_PARAM_TEST_CASE 參數:函數指針、首迭代器、尾迭代器。
夾具:RAII 風格的設置/清理
struct Fixture {
int i;
Fixture() : i(0) { /* setup */ }
~Fixture() { /* teardown */ }
};
BOOST_FIXTURE_TEST_SUITE(suite_name, Fixture)
BOOST_FIXTURE_TEST_CASE(test1, Fixture) {
BOOST_CHECK(i == 1); // 直接訪問 fixture 成員
++i;
}
BOOST_FIXTURE_TEST_CASE(test2) { // 隱式使用 suite 級 fixture
BOOST_CHECK_EQUAL(i, 1); // 每個用例獨立構造/析構 fixture
}
BOOST_AUTO_TEST_SUITE_END()
BOOST_FIXTURE_TEST_SUITE 替代 BOOST_AUTO_TEST_SUITE,指定套件級夾具
BOOST_FIXTURE_TEST_CASE 替代 BOOST_AUTO_TEST_CASE,指定用例級夾具
- **每個用例都會構造/析構一次夾具**,保證隔離性
運行時參數控制輸出
test.exe --build_info=yes --log_level=all --output_format=XML --run_test=*/test1 --show_progress=yes
| 參數 | 說明 |
log_level | success/test_suite/message/warning/error/cpp_exception/system_error/fatal_error/nothing/all |
output_format | HRF(人類可讀) / XML |
run_test | 支持通配符,如 */test1 運行所有子套件下的 test1 |
show_progress | yes 顯示進度條 |
避坑指南
- **多文件定義 BOOST_TEST_MODULE** → 鏈接錯誤
multiple definition of init_unit_test_suite。解決:僅主文件定義,其他文件只包含頭文件
- **忘記鏈接 boost_unit_test_framework** → 未定義符號。CMake:
target_link_libraries(test PRIVATE Boost::unit_test_framework)
- **浮點數比較** → 用
BOOST_CHECK_CLOSE(a, b, tolerance%) 而非 BOOST_CHECK_EQUAL
- **異常安全** →
BOOST_CHECK_NO_THROW/BOOST_CHECK_THROW/BOOST_CHECK_EXCEPTION
現代化建議
新項目可考慮 Google Test (gtest) 或 Catch2:
- 語法更簡潔(無需
BOOST_AUTO_TEST_SUITE 等宏)
- 斷言宏自動捕獲表達式文本,失敗輸出更豐富
- 原生支持 BDD 風格 (
SCENARIO/GIVEN/WHEN/THEN)
- 單頭文件部署
但 Boost.Test 仍是 Boost 生態項目、需零額外依賴場景的優秀選擇。
- 上一篇文章: C++ 成員函數重載、覆蓋、隱藏與 virtual 關鍵字深度解析
- 下一篇文章: C++ Lambda 表達式提升代碼性能與可讀性實戰
Copyright ©
程式碼之家 All Rights Reserved