五月天六月婷婷开心激情,天使的性电影,三级韩国一区久久二区综合,五月婷婷久,九九精品在线视频,66精品综合久久久久久久

您的位置:首頁 >打榜 >

嵌入式代碼單元測試如何完成?

2023-06-05 19:20:51 面包芯語

軟件開發(fā)中,每次需求的變更基本都需要改寫代碼,而代碼變更后就需要進行功能測試。當然,在功能測試之前需要代碼的單元測試,避免代碼改動后部分場景沒有驗證,最后出現(xiàn)各種問題。

常用的C語言測試框架有:


(相關(guān)資料圖)

1、Unity示例

這里介紹Unity,其他的大家感興趣可以自行查閱,不同的單元測試框架適用于不同的開發(fā)需求和場景。開發(fā)人員可以按照自己的項目要求選擇最適合的框架。

Unity最小可以只用到幾個文件即可完成,把Unity源碼目錄下的unity.cunity.hunity_internals.h三個文件復制至我們的工程目錄下進行編譯即可,然后在測試文件代碼中包含unity.h

簡單的示例

完成功能函數(shù)的驗證:

#include#include"unity.h"voidsetUp(){//這里可以放置每個測試用例運行前的初始化代碼}voidtearDown(){//這里可以放置每個測試用例運行后的清理代碼}intAdd(inta,intb){returna+b;}voidtest_AddFun(void){TEST_ASSERT_EQUAL_UINT(6,Add(1,5));TEST_ASSERT_EQUAL_UINT(4,Add(-1,5));TEST_ASSERT_EQUAL_UINT(-6,Add(-1,-5));}intmain(){UNITY_BEGIN();//啟動測試RUN_TEST(test_AddFun);UNITY_END();//結(jié)束測試return0;}

通過串口或終端打印內(nèi)容為:

C:\test/test.c:47:test_AddFun:PASS-----------------------1Tests0Failures0IgnoredOK

其中,unity_internals.h文件中可以修改輸出終端,即UNITY_OUTPUT_CHAR宏的定義。

/*-------------------------------------------------------*OutputMethod:stdout(DEFAULT)*-------------------------------------------------------*/#ifndefUNITY_OUTPUT_CHAR/*Defaulttousingputchar,whichisdefinedinstdio.h*/#include#defineUNITY_OUTPUT_CHAR(a)(void)putchar(a)#else/*Ifdefinedassomethingelse,makesurewedeclareitheresoit"sreadyforuse*/#ifdefUNITY_OUTPUT_CHAR_HEADER_DECLARATIONexternvoidUNITY_OUTPUT_CHAR_HEADER_DECLARATION;#endif#endif

其中,自定義實現(xiàn)的C語言擴展庫(cot)的容器功能函數(shù)都已通過Unity添加了對應的單元測試用例,鏈接:

2、輕量級通用擴展庫

旨在打造一個C語言的通用擴展庫。

1、介紹

支持多種容器實現(xiàn),包括通用隊列(包括不定長隊列)、棧、雙向鏈表和動態(tài)數(shù)組功能

支持定義序列化/反序列化的結(jié)構(gòu)體功能

移植了部分 C++ Boost庫中的PP庫功能

2、軟件架構(gòu)

目錄說明:

├─cot│  ├─include│  │  ├─container     // 容器實現(xiàn)頭文件│  │  ├─preprocessor  // 移植Boost庫中的PP庫頭文件│  │  └─serialize     // 序列化/反序列化實現(xiàn)頭文件│  └─src│      ├─container    // 容器實現(xiàn)源文件│      └─serialize    // 序列化/反序列化實現(xiàn)源文件├─test│  ├─container        // 容器實現(xiàn)測試代碼│  └─serialize        // 序列化/反序列化測試代碼└─unity               // 單元測試框架代碼

3、使用說明

(1)容器類功能使用說明

雙向鏈表使用方式demo:

int main(){    cotList_t list;    cotListItem_t nodeBuf[10];    cotList_Init(&list, nodeBuf, 10);    int data1 = 10;    int data2 = 20;    int data3 = 30;    // 頭部增加元素    cotList_PushFront(&list, &data1);    // 尾部增加元素    cotList_PushBack(&list, &data2);    // 插入元素    cotList_Insert(&list, cotList_End(&list), &data3);    // 使用迭代器遍歷所有元素    for_list_each(item, list)    {        printf(" = %d\n", *item_ptr(int, item));    }    // 移除指定元素    cotList_Remove(&list, &data3);    // 根據(jù)添加移除元素    cotList_RemoveIf(&list, OnRemoveCondition);    cotList_t list2;    cotListItem_t nodeBuf2[3];    cotList_Init(&list2, nodeBuf2, 3);    // 鏈表內(nèi)存交換    cotList_Swap(&list1, &list2);    return 0;}

動態(tài)數(shù)組使用方式demo:

int main(){    uint8_t buf[20];    cotVector_t vector;    cotVector_Init(&vector, buf, sizeof(buf), sizeof(uint32_t));    // 在尾部追加元素    uint32_t data = 42;    cotVector_Push(&vector, &data);    data = 56;    cotVector_Push(&vector, &data);    data = 984;    cotVector_Push(&vector, &data);    // 插入元素    uint32_t arrdata[2] = {125, 656};    cotVector_InsertN(&vector, 2, &arrdata, 2);    // 刪除兩個元素    cotVector_RemoveN(&vector, 1, 2);    // 根據(jù)添加刪除元素    cotVector_RemoveIf(&vector, OnVectorRemoveCondition);    // 打印數(shù)組中的數(shù)據(jù)內(nèi)容    for (int i = 0; i < cotVector_Size(&vector); i++)    {        printf("%02x ", cotVector_Data(&vector)[i]);    }    return 0;}
int main(){    uint8_t buf[10];    cotQueue_t queue;    cotQueue_Init(&queue, buf, sizeof(buf), sizeof(int));    // 在尾部追加元素    int data = 42;    cotQueue_Push(&queue, &data, sizeof(data));    data = 895;    cotQueue_Push(&queue, &data, sizeof(data));    // 訪問元素    int *pData = (int *)cotQueue_Front(&queue);    printf("val = %d \n", *pData);    // 彈出首個元素    cotQueue_Pop(&queue);    return 0;}

隊列(不定長FIFO)使用方式demo:

int main(){    uint8_t buf[10];    cotIndQueue_t queue;    cotIndQueue_Init(&queue, buf, sizeof(buf));    // 在尾部追加元素    char data = 42;    cotIndQueue_Push(&queue, &data, sizeof(data));    int data1 = 80;    cotIndQueue_Push(&queue, &data, sizeof(data1));    long data2 = -400;    cotIndQueue_Push(&queue, &data, sizeof(data2));    // 訪問元素    size_t length;    int *pData = (int *)cotIndQueue_Front(&queue, &length);    printf("val = %d \n", *pData, length);    // 彈出首個元素    cotIndQueue_Pop(&queue);    return 0;}
int main(){    uint8_t buf[10];    cotStack_t stack;    cotStack_Init(&stack, buf, sizeof(buf), sizeof(int));    // 在頂部追加元素    int data = 42;    cotStack_Push(&stack, &data, sizeof(data));    data = 895;    cotQueue_Push(&stack, &data, sizeof(data));    // 訪問元素    int *pData = (int *)cotStack_Top(&stack);    printf("val = %d \n", *pData);    // 彈出頂部元素    cotStack_Pop(&stack);    return 0;}

(2)序列化/反序列化功能使用說明

可以定義一個公共頭文件:

#ifndef STRUCT_H#define STRUCT_H#include "serialize/serialize.h"COT_DEFINE_STRUCT_TYPE(test_t,    ((UINT16_T)     (val1)      (2))    ((INT32_T)      (val2)      (1))     ((UINT8_T)      (val3)      (1))    ((INT16_T)      (val4)      (1))    ((DOUBLE_T)     (val5)      (1))     ((INT16_T)      (val6)      (1))    ((STRING_T)     (szName)    (100))    ((DOUBLE_T)     (val7)      (1))     ((FLOAT_T)      (val8)      (1))    ((STRING_T)     (szName1)   (100)))#endif // STRUCT_H
#include "struct.h"int main(){    uint8_t buf[100];    // 序列化使用demo    COT_DEFINE_STRUCT_VARIABLE(test_t, test);    test.val1[0] = 5;    test.val1[1] = 89;    test.val2 = -9;    test.val3 = 60;    test.val4 = -999;    test.val5 = 5.6;    test.val6 = 200;    test.val7 = -990.35145;    test.val8 = -80.699;    sprintf(test.szName, "test56sgdgdfgdfgdf");    sprintf(test.szName1, "sdfsdf");    int length = test.Serialize(buf, &test);    printf("Serialize: \n");    for (int i = 0; i < length; i++)    {        printf("%02x %s", buf[i], (i + 1) % 16 == 0 ? "\n" : "");    }    printf("\n");    // 反序列化使用demo    test_t test2;           // COT_DEFINE_STRUCT_VARIABLE(test_t, test2);    COT_INIT_STRUCT_VARIABLE(test_t, test2);    test2.Parse(&test2, buf);    printf("val = %d\n", test2.val1[0]);    printf("val = %d\n", test2.val1[1]);    printf("val = %d\n", test2.val2);    printf("val = %d\n", test2.val3);    printf("val = %d\n", test2.val4);    printf("val = %lf\n", test2.val5);    printf("val = %d\n", test2.val6);    printf("name = %s\n", test2.szName);    printf("val = %lf\n", test2.val7);    printf("val = %f\n", test2.val8);    printf("name = %s\n", test2.szName1);    return 0;}

標簽:


        
精彩推薦

 

主站蜘蛛池模板: 污小说总裁整夜没拔出| 3d动漫啪啪| 精品国产污污免费网站入口| 欧美va在线高清| 精品一区二区三区在线观看视频| 中文字幕ヘンリー冢本全集| 无人视频免费观看免费视频| 无翼少无翼恶女漫画全彩app| 国产一区二区精品| 在线免费观看你懂的| 国漫永生第二季在线观看| 男生和女生一起差差的视频30分| 最近高清中文在线国语字幕| 蜜桃成熟时2005| 欧美在线不卡| 正在播放久久| 啊灬啊灬别停啊灬用力啊免费 | 日本黄色片免费观看| 丁香狠狠色婷婷久久综合| 冬月枫亚洲高清在线观看| 国产精品成人va在线观看| 亚洲欧美日韩中文无线码| 日本动态120秒免费| 啊v在线观看| 女人张开腿等男人桶免费视频| 一本久久a久久精品vr综合| 精品一区二区久久久久久久网站| 毛片aa| 午夜爽爽视频| 快点cao我要被cao烂了| 夜夜揉揉日日人人视频| 人妖在线| 亚洲成a人片在线观看www| 两人夜晚打扑克剧烈运动| 四虎影视永久地址www成人| 腿张大点我就可以吃扇贝了| 黄色a级片电影| 波多野结衣cesd—819| 免费日本黄色片| 国产大片中文字幕在线观看| 国产精品日韩欧美一区二区三区|