• 正文
  • 相關(guān)推薦
申請(qǐng)入駐 產(chǎn)業(yè)圖譜

嵌入式軟件,有必要進(jìn)行自測(cè)嗎?

04/02 09:50
356
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點(diǎn)資訊討論

大家好,我是雜燴君。

本次我們來(lái)介紹嵌入式可測(cè)試軟件設(shè)計(jì)。

什么是可測(cè)試性?就是你這個(gè)軟件模塊/函數(shù)接口寫完之后,可以較為方便、較為全面地進(jìn)行自測(cè) 。

作為嵌入式軟件開(kāi)發(fā)者,我們?cè)陂_(kāi)發(fā)自己負(fù)責(zé)的模塊之前,大家事先會(huì)做什么?

在公司沒(méi)有規(guī)定要寫文檔的情況下,可能我們很多人會(huì)直接開(kāi)干、寫代碼。

一些對(duì)自己模塊比較負(fù)責(zé)的人,會(huì)寫設(shè)計(jì)文檔,用于評(píng)審或者供給其他同事看。

我個(gè)人覺(jué)得,在寫代碼之前,除了寫設(shè)計(jì)文檔,還有一點(diǎn)很重要:思考我們的模塊如何進(jìn)行自測(cè)。

軟件迭代,大多公司的過(guò)程如下:

軟件工程師開(kāi)發(fā) -> 釋放版本 -> 測(cè)試工程師測(cè)試 -> 軟件工程師修bug -> 釋放版本 -> ...

每次發(fā)現(xiàn)一個(gè)bug,這個(gè)bug修復(fù)的周期會(huì)很長(zhǎng)。

所以,我們盡可能地在釋放給測(cè)試之前,進(jìn)行一個(gè)完整的自測(cè),減少一些不必要的bug產(chǎn)生(主路徑bug)。

增加一個(gè)步驟:

軟件工程師開(kāi)發(fā) ->?軟件工程師自測(cè)?-> 釋放版本 -> 測(cè)試工程師測(cè)試 -> 軟件工程師修bug -> 釋放版本 -> ...

軟件工程師自測(cè),這個(gè)在我們嵌入式行業(yè),很多大公司可能會(huì)作為一個(gè)標(biāo)準(zhǔn)的流程。但是在一些中小公司,可能會(huì)忽略這個(gè)步驟,那這就靠我們自覺(jué)了。因?yàn)檫M(jìn)行充分的自測(cè),受益的也是我們,免去了后面反復(fù)地被bug修復(fù)打斷我們的需求開(kāi)發(fā)。

其實(shí),我們自己模塊的開(kāi)發(fā),除了供給測(cè)試工程師測(cè)試之外。有時(shí)候,我們也會(huì)供給我們的團(tuán)隊(duì)成員調(diào)用,或是其他部門的同事使用,我們?cè)诮桓冻鋈ミM(jìn)行聯(lián)調(diào)之前,需要保證質(zhì)量,也能免去后面很多的聯(lián)調(diào)成本。

建議大家,寫代碼之前,寫個(gè)文檔,里面包含:

    自測(cè)的思考設(shè)計(jì)思路

并且自測(cè)的思考放在設(shè)計(jì)之前。需要先思考如何自測(cè),因?yàn)樵谒伎甲詼y(cè)的時(shí)候,會(huì)對(duì)我們的設(shè)計(jì)也是有幫助的。

舉個(gè)簡(jiǎn)單的例子來(lái)認(rèn)識(shí)可測(cè)試性程序。

有一個(gè)計(jì)算函數(shù)cal_func,其計(jì)算依賴于存在flash里的數(shù)據(jù)a,與一個(gè)外部輸入的數(shù)據(jù)b。

此時(shí),有如下兩種實(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);

這種類似場(chǎng)景,實(shí)際開(kāi)發(fā)中應(yīng)該有不少,大家平時(shí)都是按照方式一寫代碼還是方式二寫代碼呢?

從可測(cè)試性的角度來(lái)看,?方法二的實(shí)現(xiàn),更具備可測(cè)試性?。

我們寫完代碼,一般為了保證質(zhì)量我們要進(jìn)行充分的測(cè)試。

方式一,因?yàn)橛幸粋€(gè)數(shù)據(jù)是在函數(shù)內(nèi)部從flash中讀取的,所以這個(gè)數(shù)據(jù)我們不太方便進(jìn)行控制,而能控制的只有參數(shù)b。那么,這樣子,我們?cè)谡{(diào)用測(cè)試時(shí),測(cè)得就不是很全,也不能靈活地控制測(cè)試路徑。

方式二,計(jì)算所依賴的數(shù)據(jù)都通過(guò)函數(shù)參數(shù)留出來(lái)了,我們可以很方便地對(duì)函數(shù)進(jìn)行測(cè)試,可以很方便地輸入不同的數(shù)據(jù)組合。

并且,一般地,我們會(huì)引入一些?單元測(cè)試框架?,用來(lái)統(tǒng)一管理我們的測(cè)試?yán)印?/p>

嵌入式中,常用的測(cè)試框架:

    Unity:https://github.com/ThrowTheSwitch/Unity/releasescutest:https://sourceforge.net/projects/cutest/embunit :https://sourceforge.net/projects/embunitgoogletest:https://github.com/google/googletest/releases

使用測(cè)試框架之后,針對(duì)cal_func函數(shù)設(shè)計(jì)的測(cè)試代碼如:

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;
}

我們封裝成串口測(cè)試指令:

// 測(cè)試路徑1
ut app ut_cal_func?1?2?3
? ??
// 測(cè)試路徑2
ut app ut_cal_func?2?3?5
? ??
// ...

輸出:

input 1, 2,?test?pass!
input 2, 3,?test?pass!

這就是一個(gè)可測(cè)試性軟件設(shè)計(jì)的一個(gè)小例子,通過(guò)這個(gè)小例子大家應(yīng)該認(rèn)識(shí)到可測(cè)試性軟件的好處了吧?

所以,之后寫代碼,寫之前,有必要先想清楚,這個(gè)模塊最后要怎么進(jìn)行自測(cè)?要測(cè)哪些地方?

設(shè)計(jì)的軟件可測(cè)試性強(qiáng),我們就能在開(kāi)發(fā)階段進(jìn)行充分地測(cè)試,在開(kāi)發(fā)階段盡可能多地解決一些邏輯上的問(wèn)題,從而保證更高質(zhì)量地軟件交付。

以上就是本次的分享,歡迎收藏、轉(zhuǎn)發(fā)!

相關(guān)推薦

登錄即可解鎖
  • 海量技術(shù)文章
  • 設(shè)計(jì)資源下載
  • 產(chǎn)業(yè)鏈客戶資源
  • 寫文章/發(fā)需求
立即登錄

本公眾號(hào)專注于嵌入式技術(shù),包括但不限于C/C++、嵌入式、物聯(lián)網(wǎng)、Linux等編程學(xué)習(xí)筆記,同時(shí),公眾號(hào)內(nèi)包含大量的學(xué)習(xí)資源。歡迎關(guān)注,一同交流學(xué)習(xí),共同進(jìn)步!