大家好,我是雜燴君。
什么是可測試性?就是你這個軟件模塊/函數接口寫完之后,可以較為方便、較為全面地進行自測?。
舉個簡單的例子來認識可測試性軟件。
有一個計算函數cal_func,其計算依賴于存在flash里的數據a,與一個外部輸入的數據b。
此時,有如下兩種實現方法:
方法一:
int?get_a_from_flash(void)
{
?int?a?=?0;
?flash_read(&a,?sizeof(int));
?
?return?a;
}
int?cal_func(int?b)
{
?int?res?=?0;
?int?a?=?get_a_from_flash();
?
?res?=?a?+?b;
?
?return?res;
}
//?調用
cal_func(5);
方法二:
int?get_a_from_flash(void)
{
?int?a?=?0;
?flash_read(&a,?sizeof(int));
?
?return?a;
}
int?cal_func(int?a,?int?b)
{
?int?res?=?0;
?
?res?=?a?+?b;
?
?return?res;
}
//?調用
cal_func(get_a_from_flash(),?5);
這種類似場景,實際開發(fā)中應該有不少,大家平時都是按照方式一寫代碼還是方式二寫代碼呢?
從可測試性的角度來看, 方法二的實現,更具備可測試性
。
方式一,因為有一個數據是在函數內部從flash中讀取的,所以這個數據我們不太方便進行控制,而能控制的只有參數b。那么,這樣子,我們在調用測試時,測得就不是很全,也不能靈活地控制測試路徑。
方式二,計算所依賴的數據都通過函數參數留出來了,我們可以很方便地對函數進行測試,可以很方便地輸入不同的數據組合。
并且,一般地,我們會引入一些 單元測試框架
,用來統(tǒng)一管理我們的測試例子。
嵌入式中,常用的測試框架:
- Unity:https://github.com/ThrowTheSwitch/Unity/releasescutest:https://sourceforge.net/projects/cutest/embunit :https://sourceforge.net/projects/embunitgoogletest:https://github.com/google/googletest/releases
使用測試框架之后,針對cal_func函數設計的測試代碼如:
int?ut_cal_func(int?argc,?char?*argv[])
{
????if?(argc?!=?3)
????{
????????printf("Param?num?errn");
????????return?USAGE;
????}
????//?預期結果
????int?expected_res?=?atoi(argv[2]);?
????//?實際結果??????????????????
?int?res?=?cal_func(atoi(argv[0]),?atoi(argv[1]));???
????if?(expected_res?==?res)
????{
????????printf("input?%d,?%d,?test?pass!n",?atoi(argv[0]),?atoi(argv[1]));
????}
????else
????{
????????printf("input?%d,?%d,?test?failed!n",?atoi(argv[0]),?atoi(argv[1]));
????}
?return?0;
}
我們封裝成串口測試指令:
//?測試路徑1
ut?app?ut_cal_func?1?2?3
????
//?測試路徑2
ut?app?ut_cal_func?2?3?5
????
//?...
輸出:
input?1,?2,?test?pass!
input?2,?3,?test?pass!
這就是一個可測試性軟件設計的一個小例子,通過這個小例子大家應該認識到可測試性軟件的好處了吧?
所以,之后寫代碼,寫之前,有必要先想清楚,這個模塊最后要怎么進行自測?要測哪些地方?
設計的軟件可測試性強,我們就能在開發(fā)階段進行充分地測試,在開發(fā)階段盡可能多地解決一些邏輯上的問題,從而保證更高質量地軟件交付。
以上就是本次的分享,歡迎收藏、轉發(fā)!