作為一名C語言開發工程師,我們都知道單元測試對於保證代碼質量是至關重要的。而criterion正是一個為C語言開發者所設計的單元測試框架,可以幫助我們更方便地進行單元測試。本文將會從多個方面闡述criterion的使用方法及其優勢。
一、快速入門
使用criterion編寫單元測試非常簡單,只需包含criterion頭文件並在main函數中編寫測試用例即可。我們以一個簡單的例子來說明:
#include <criterion/criterion.h>
int square(int num) {
return num * num;
}
Test(my_tests, square_of_zero) {
cr_assert_eq(0, square(0));
}
Test(my_tests, square_of_positive) {
cr_assert_eq(4, square(2));
cr_assert_eq(9, square(3));
}
Test(my_tests, square_of_negative) {
cr_assert_eq(9, square(-3));
}
上述代碼將會測試square函數三個不同輸入情況下的輸出是否符合預期。我們使用了cr_assert_eq斷言來判斷程序輸出是否和預期一致。
二、使用斷言
criterion提供的斷言非常豐富,可以滿足大部分的單元測試需求。以下是一些常用的斷言:
cr_assert(expr)
– 判斷表達式expr是否為真cr_assert_eq(val1, val2)
– 判斷val1和val2是否相等cr_assert_neq(val1, val2)
– 判斷val1和val2是否不相等cr_assert_lt(val1, val2)
– 判斷val1是否小於val2cr_assert_leq(val1, val2)
– 判斷val1是否小於等於val2cr_assert_gt(val1, val2)
– 判斷val1是否大於val2cr_assert_geq(val1, val2)
– 判斷val1是否大於等於val2
我們將會在接下來的測試用例中使用這些斷言對我們寫的函數進行測試。
三、隔離測試
在實際的測試中,我們有時候需要對某個函數進行測試,但是這個函數所依賴的其他函數可能還沒有被實現或者還沒有測試通過。這個時候,我們可以使用criterion提供的mock功能。以下是一個示例:
#include <criterion/criterion.h>
// 我們要測試的函數
int sum(int a, int b) {
return a + b + 1; // 為了方便演示,故意寫成了a+b+1,實際上應該是a+b
}
// mock依賴的函數
int add_one(int num) {
return num + 1;
}
Test(my_tests, sum_of_positive) {
// 設定mock
cr_mock(add_one, int, (int num), { return num; });
// 進行測試
cr_assert_eq(4, sum(1, 2));
// 取消mock
cr_unmock(add_one);
}
我們通過設定mock將add_one函數的輸出設定為輸入值本身,使得測試用例可以順利運行,而不需要考慮add_one函數的實際實現。
四、集成其他測試框架
criterion還可以集成其他測試框架,如CMocka和Unity。我們只需要引入criterion_adapter頭文件並使用宏即可:
#include <criterion/criterion.h>
#include <criterion/criterion_adapter.h>
// 集成CMocka
#define CTEST_SEGFAULT cr_assert_fail("segmentation fault");
#define CTEST_ABORT cr_skip_test("aborted");
void segfault_test(void **state) {
int *a = NULL;
*a = 1;
}
Test(my_tests, using_cmocka,
.init = cr_redirect_stderr,
.signal = CTEST_SEGFAULT,
.abort = CTEST_ABORT) {
const UnitTest tests[] = {
unit_test(segfault_test),
};
return cmocka_run_group_tests(tests, NULL, NULL);
}
// 集成Unity
Test(my_tests, using_unity) {
cr_run_test(UnityMain(argc, argv, RunAllTests));
}
上述代碼分別演示了如何集成CMocka和Unity,並且展示了如何使用criterion提供的宏。我們可以通過串聯測試用例和使用.init、.signal、.abort三個參數來達到我們需要的測試效果。
五、自定義輸出
有時候我們需要對測試結果進行自定義輸出,criterion也提供了這個功能。以下是一個示例:
#include <criterion/criterion.h>
Test(my_tests, custom_output,
.init = cr_redirect_stdout,
.fini = cr_assert_stdout_eq_str("Output for my test\n")) {
printf("Output for my test\n");
}
我們使用cr_redirect_stdout將標準輸出重定向到一個緩衝區中,並使用cr_assert_stdout_eq_str斷言判斷緩衝區中的輸出是否和預期一致。
六、總結
本文從快速入門、使用斷言、隔離測試、集成其他測試框架、自定義輸出等多個方面對criterion進行了詳細的闡述。希望本文可以幫助到初學者了解criterion的使用方法,並且能夠更好地進行C語言單元測試工作。
原創文章,作者:KEOGJ,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/370911.html