大家好,我是雜燴君。
什么是可測試性?就是你這個軟件模塊/函數(shù)接口寫完之后,可以較為方便、較為全面地進(jìn)行自測 。
作為嵌入式軟件開發(fā)者,我們在開發(fā)自己負(fù)責(zé)的模塊之前,大家事先會做什么?
在公司沒有規(guī)定要寫文檔的情況下,可能我們很多人會直接開干、寫代碼。
一些對自己模塊比較負(fù)責(zé)的人,會寫設(shè)計文檔,用于評審或者供給其他同事看。
我個人覺得,在寫代碼之前,除了寫設(shè)計文檔,還有一點(diǎn)很重要:思考我們的模塊如何進(jìn)行自測。
軟件迭代,大多公司的過程如下:
軟件工程師開發(fā) -> 釋放版本 -> 測試工程師測試 -> 軟件工程師修bug -> 釋放版本 -> ...
每次發(fā)現(xiàn)一個bug,這個bug修復(fù)的周期會很長。
所以,我們盡可能地在釋放給測試之前,進(jìn)行一個完整的自測,減少一些不必要的bug產(chǎn)生(主路徑bug)。
增加一個步驟:
軟件工程師開發(fā) ->?軟件工程師自測?-> 釋放版本 -> 測試工程師測試 -> 軟件工程師修bug -> 釋放版本 -> ...
軟件工程師自測,這個在我們嵌入式行業(yè),很多大公司可能會作為一個標(biāo)準(zhǔn)的流程。但是在一些中小公司,可能會忽略這個步驟,那這就靠我們自覺了。因為進(jìn)行充分的自測,受益的也是我們,免去了后面反復(fù)地被bug修復(fù)打斷我們的需求開發(fā)。
其實(shí),我們自己模塊的開發(fā),除了供給測試工程師測試之外。有時候,我們也會供給我們的團(tuán)隊成員調(diào)用,或是其他部門的同事使用,我們在交付出去進(jìn)行聯(lián)調(diào)之前,需要保證質(zhì)量,也能免去后面很多的聯(lián)調(diào)成本。
建議大家,寫代碼之前,寫個文檔,里面包含:
- 自測的思考設(shè)計思路
并且自測的思考放在設(shè)計之前。需要先思考如何自測,因為在思考自測的時候,會對我們的設(shè)計也是有幫助的。
舉個簡單的例子來認(rèn)識可測試性程序。
有一個計算函數(shù)cal_func,其計算依賴于存在flash里的數(shù)據(jù)a,與一個外部輸入的數(shù)據(jù)b。
此時,有如下兩種實(shí)現(xiàn)方法:
方法一:
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;
}
// 調(diào)用
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;
}
// 調(diào)用
cal_func(get_a_from_flash(),?5);
這種類似場景,實(shí)際開發(fā)中應(yīng)該有不少,大家平時都是按照方式一寫代碼還是方式二寫代碼呢?
從可測試性的角度來看,?方法二的實(shí)現(xiàn),更具備可測試性
?。
我們寫完代碼,一般為了保證質(zhì)量我們要進(jìn)行充分的測試。
方式一,因為有一個數(shù)據(jù)是在函數(shù)內(nèi)部從flash中讀取的,所以這個數(shù)據(jù)我們不太方便進(jìn)行控制,而能控制的只有參數(shù)b。那么,這樣子,我們在調(diào)用測試時,測得就不是很全,也不能靈活地控制測試路徑。
方式二,計算所依賴的數(shù)據(jù)都通過函數(shù)參數(shù)留出來了,我們可以很方便地對函數(shù)進(jìn)行測試,可以很方便地輸入不同的數(shù)據(jù)組合。
并且,一般地,我們會引入一些?單元測試框架
?,用來統(tǒng)一管理我們的測試?yán)印?/p>
嵌入式中,常用的測試框架:
- 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函數(shù)設(shè)計的測試代碼如:
int?ut_cal_func(int?argc,?char?*argv[])
{
? ??if?(argc !=?3)
? ? {
? ? ? ??printf("Param num errn");
? ? ? ??return?USAGE;
? ? }
? ??// 預(yù)期結(jié)果
? ??int?expected_res = atoi(argv[2]);?
? ??// 實(shí)際結(jié)果 ? ? ? ? ? ? ? ? ?
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]));
? ? }
return0;
}
我們封裝成串口測試指令:
// 測試路徑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!
這就是一個可測試性軟件設(shè)計的一個小例子,通過這個小例子大家應(yīng)該認(rèn)識到可測試性軟件的好處了吧?
所以,之后寫代碼,寫之前,有必要先想清楚,這個模塊最后要怎么進(jìn)行自測?要測哪些地方?
設(shè)計的軟件可測試性強(qiáng),我們就能在開發(fā)階段進(jìn)行充分地測試,在開發(fā)階段盡可能多地解決一些邏輯上的問題,從而保證更高質(zhì)量地軟件交付。
以上就是本次的分享,歡迎收藏、轉(zhuǎn)發(fā)!