0


C语言-单元测试(自研)

前沿

单元测试(unit testing),是指对软件中的最小可测试单元进行检查和验证。对于单元测试中单元的含义,一般来说,要根据实际情况去判定其具体含义,如C语言中单元指一个函数,Java里单元指一个类,图形化的软件中可以指一个窗口或一个菜单等。总的来说,单元就是人为规定的最小的被测功能模块。单元测试是在软件开发过程中要进行的最低级别的测试活动,软件的独立单元将在与程序的其他部分相隔离的情况下进行测试。

在网上找了找C语言都没有类似java 的junit单元测试 ,反复测试自己写的模块非常费劲,特别是交叉模块测试的时候根本就无法弄

因为一个程序只允许一个main方法,如果其他地方存在了,那么就会报错,这就导致了测完A模块想要测试B模块就需要把A模块测试的相关内容删除,这样会出现什么问题呢? 如果后期我们对A模块的内容进行了修改,那么是不是需要在重新写一套测试Demo, 这样非常浪费时间和精力 ,没办法只能自己开发一套类似的,来协助本地开发进行测试代码

  1. 实现最小单元以函数进行测试
  2. 实现流程测试
  3. 实现模块交互模块测试

使用前提

自己必须有集合数据结构和hash结构,然后根据下面的代码进行修改即可 ,如果没有可以到我博客里学习

测试结构

在这里插入图片描述

断言

#ifndefSTUDY_ASSERTMY_H#defineSTUDY_ASSERTMY_H//设置字体颜色 (只是在windward下有效)#definecolor(x)SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), x)#defineassertErrorMessageTest(_Expression,errorMessage)\do\{\if((_Expression)){\color(2);\printf("==============================: method:%s --->  (%s)Assertion success\n ",__func__,#_Expression);\};\color(7);\if(!(_Expression)){\color(4);\printf("==============================: (%s)\n Assertion failed: (%s), file:%s \nmethod:%s , line %d \n", errorMessage, #_Expression,__FILE__,__func__,__LINE__);\exit(0);\color(7);\};\}while(0)#defineassertMessageMoreTest(_Expression,correctMessage, errorMessage)\do\{\if((_Expression)){\color(2);\printf("==============================: (%s)\n Assertion success: (%s) , method:%s \n   ",correctMessage,__func__,#_Expression);\};\color(7);\if(!(_Expression)){\color(4);\printf("==============================: (%s)\n Assertion failed: (%s), file:%s \nmethod:%s , line %d \n", errorMessage, #_Expression,__FILE__,__func__,__LINE__);\exit(0);\color(7);\};\}while(0)#defineassertTest(_Expression)\do\{\if(!(_Expression)){\color(4);\printf("Assertion failed: (%s), file:%s \nmethod:%s , line %d \n", #_Expression,__FILE__,__func__,__LINE__);\exit(0);\color(7);\};\}while(0)#endif//STUDY_ASSERTMY_H

核心代码

#ifndefSTUDY_TESTCORE_H#defineSTUDY_TESTCORE_H#include"../../structure/charlinkedhashmap.h"#include"../../structure/char_kv_orderly_list.h"#include"../assertmy.h"#include<windows.h>typedefint BOOL;//定义一个布尔类型#defineTRUE1#defineFALSE0typedefvoid(*TestMethod)(void);typedefvoid(TestGroupMethod)(void);typedefstructtestCore{char methodName[100];//方法名
    BOOL methodState;//方法状态void*method;//方法} TestCore;typedefstructtestGroup{char groupName[100];//组名
    BOOL groupState;//组状态} TestGroup;voidaddTestGroup(char*testGroupName,BOOL state, Long order, TestGroupMethod testGroupMethod);voidtest_Run_Core_MethodAll();voidtest_Run_Core_Method(char*methodName);voidaddTestMethodName(constchar*groupId,char*methodName, BOOL state, Long order, TestMethod testMethod);voidtest_Run_Core_Group(char*testGroupName);voidtest_Run_Core_Group_ALL();#endif//STUDY_TESTCORE_H
#include"testcore.h"#include<string.h>#include"assert.h"static CharLinkedHashMap *testCore =NULL;static CharKvOrderlyList *testGroup =NULL;#defineMAXSCORE2147483647#defineMINCORE-2147483648#defineLIMIT(x)(assert(x>=MINCORE&&x<=MAXSCORE))

Long groupCount =1;//记录第几组#defineaddOrder(x) x->sort=groupCount*MAXSCORE+x->sort;//创建测试核心
TestCore *createTestCore(char*methodName, BOOL state, TestMethod testMethod){
    TestCore *testCore =malloc(sizeof(TestCore));
    testCore->methodState = state;
    testCore->method = testMethod;strcpy(testCore->methodName, methodName);return testCore;}//创建测试组
TestGroup *createTestGroup(char*groupName, BOOL state){
    TestGroup *testGroup =malloc(sizeof(TestGroup));
    testGroup->groupState = state;strcpy(testGroup->groupName, groupName);return testGroup;}/**
 *
 * @param groupId     __FUNCTION__   使用宏获取当前方法名代来作为测试组名
 * @param methodName   方法名
 * @param testMethod     需要运行的方法
 * @param state     方法状态TRUE启用 FALSE禁用
 * @param order     执行的顺序 (值越大越靠后)
 */voidaddTestMethodName(constchar*groupId,char*methodName, BOOL state, Long order, TestMethod testMethod){LIMIT(order);//判定order是否在范围内if(testCore ==NULL){
        testCore =createCharLinkedHashMap(200);}void*pVoid =getCharLinkedHashMap(testCore, groupId);if(pVoid ==NULL){
        CharKvOrderlyList *pList =createCharKvOrderlyList(200);
        TestCore *pCore =createTestCore(methodName, state, testMethod);addCharKvOrderlyList(pList, methodName, pCore, order);putCharLinkedHashMap(testCore, groupId, pList);}else{
        CharKvOrderlyList *pList =(CharKvOrderlyList *) pVoid;
        TestCore *pCore =createTestCore(methodName, state, testMethod);addCharKvOrderlyList(pList, methodName, pCore, order);}}/**
 * 运行指定的测试方法
 * @param methodName
 * @param initMethod
 */voidtest_Run_Core_Method(char*methodName){
    CharList *pCharlist =keysCharLinkedHashMap(testCore);//迭代测试组for(int i =0; i < pCharlist->len; i++){char*groupId = pCharlist->str[i];
        CharKvOrderlyList *pList =getCharLinkedHashMap(testCore, groupId);
        CharKvOrderlyListData *pData =getCharKvOrderlyListByKey(pList, methodName);if(pData!=NULL){
            TestCore *testCore1 =(TestCore *) pData->data;
            TestMethod pVoid = testCore1->method;pVoid();return;}}}/**
 * 运行所有的测试方法,如果方法状态为FALSE则跳过
 * @param initMethod
 */voidtest_Run_Core_MethodAll(){//根据指定的顺序执行
    CharLinkedHashIterator *pHashIterator =createCharLinkedHashMapIterator(testCore);while(hasNextCharLinkedHashMapIterator(pHashIterator)){
        CharKvLinkedNode *pNode =nextCharLinkedHashMapIterator(pHashIterator);//拿到方法名//拿到测试组的方法并且运行
        CharKvOrderlyListIterator *pListIterator =createCharKvOrderlyListIterator(pNode->value);while(hasNextCharKvOrderlyList(pListIterator)){
            CharKvOrderlyListData *pData =(CharKvOrderlyListData *)nextCharKvOrderlyList(pListIterator);//拿到方法名
            TestCore *testCore1 =   pData->data;if(testCore1->methodState == TRUE){
                TestMethod pVoid = testCore1->method;pVoid();}}}}//添加测试组voidaddTestGroup(char*testGroupName,BOOL state, Long order, TestGroupMethod testGroupMethod){if(testGroup ==NULL){
        testGroup =createCharKvOrderlyList(200);}testGroupMethod();//执行测试组方法载入测试容器里面//添加测试组
    TestGroup *testGroup1 =createTestGroup(testGroupName, state);addCharKvOrderlyList(testGroup, testGroupName, testGroup1, order);//获取组内的所有的方法,然后从新计算排序分值
    CharKvOrderlyList *pNode =(CharKvOrderlyList *)getCharLinkedHashMap(testCore, testGroupName);
    CharKvOrderlyListIterator *pListIterator =createCharKvOrderlyListIterator(pNode);while(hasNextCharKvOrderlyList(pListIterator)){
        CharKvOrderlyListData *pData =(CharKvOrderlyListData *)nextCharKvOrderlyList(pListIterator);//拿到方法名addOrder(pData);}
    groupCount++;quickSort(pNode);//重新排序}voidtest_Run_Core_Group(char*testGroupName){
    CharKvOrderlyList *pNode =(CharKvOrderlyList *)getCharLinkedHashMap(testCore, testGroupName);if(pNode==NULL){return;}//拿到测试组的方法并且运行
    CharKvOrderlyListIterator *pListIterator =createCharKvOrderlyListIterator(pNode);while(hasNextCharKvOrderlyList(pListIterator)){
        CharKvOrderlyListData *pData =(CharKvOrderlyListData *)nextCharKvOrderlyList(pListIterator);//拿到方法名
        TestCore *testCore1 =   pData->data;if(testCore1->methodState == TRUE){
            TestMethod pVoid = testCore1->method;pVoid();}}}voidtest_Run_Core_Group_ALL(){//根据指定的顺序执行
    CharKvOrderlyListIterator *pListIterator =createCharKvOrderlyListIterator(testGroup);while(hasNextCharKvOrderlyList(pListIterator)){
        CharKvOrderlyListData *pData =(CharKvOrderlyListData *)nextCharKvOrderlyList(pListIterator);//拿到方法名
        TestGroup *testGroup1 =(TestGroup *) pData->data;if(testGroup1->groupState == TRUE){test_Run_Core_Group(testGroup1->groupName);}}}

测试组装工厂

#ifndefSTUDY_TESTFACTORY_H#defineSTUDY_TESTFACTORY_H#include"../structure/charlinkedhashmap.h"#include"../structure/char_kv_orderly_list.h"#include"testcore/testcore.h"typedefvoid(*TestFun)(void);voidtest_Run_Method(char*methodName);voidtest_Run_GroupAll_MethodAlL();voidtest_Run_Group(char*groupMethodName);voidtestMain(TestFun testFun);#endif//STUDY_TESTFACTORY_H
#include"testfactory.h"#include<stdio.h>static  BOOL test_init_of=FALSE;//测试初始化voidtest_Run_Method(char*methodName){assertTest(test_init_of);test_Run_Core_Method(methodName);}voidtest_Run_GroupAll_MethodAlL(){assertTest(test_init_of);test_Run_Core_MethodAll();}voidtest_Run_Group(char*groupMethodName){assertTest(test_init_of);test_Run_Core_Group(groupMethodName);}voidtestMain(TestFun testFun){testFun();
    test_init_of=TRUE;}

编写测试Demo(演示)

#ifndefSTUDY_TEST_CHARLIST_DEMO_H#defineSTUDY_TEST_CHARLIST_DEMO_Hvoidtest_charlist_demo_init_method();#endif//STUDY_TEST_CHARLIST_DEMO_H
#include"test_charlist_demo.h"#include"../../structure/charlist.h"#include<stdio.h>#include"../testcore/testcore.h"static CharList *pCharlist;voidtest_create_charlist_demo(){
    pCharlist =createCharList(200);assertErrorMessageTest(pCharlist,"createCharList创建失败");}voidtest_add_charlist_demo(){char*str ="hello";char*str2 ="world";char*str3 ="!";char*str4 ="hu";char*str5 ="an";char*str6 ="min";addCharList(pCharlist, str);addCharList(pCharlist, str2);addCharList(pCharlist, str3);addCharList(pCharlist, str4);addCharList(pCharlist, str5);addCharList(pCharlist, str6);assertErrorMessageTest(pCharlist->len ==6,"addCharList添加失败");}voidtest_get_charlist_demo(){char*str ="hello";int i =charListBinarySearch(pCharlist, str);char message[100];sprintf(message,"charListBinarySearch查找成功,查找的位置为%d", i);assertMessageMoreTest(i !=-1,message,"charListBinarySearch查找失败");}voidtest_del_charlist_demo(){char*str ="hello";int value =deleteCharListByValue(pCharlist, str);char message[100];sprintf(message,"deleteCharListByValue删除成功,删除的位置为%d", value);assertMessageMoreTest(value,message,"delCharList删除失败");}voidtest_del_index_charlist_demo(){int i =deleteCharListByIndex(pCharlist,0);char message[100];sprintf(message,"deleteCharListByIndex删除成功,删除的位置为%d", i);assertMessageMoreTest( i !=-1,message,"delCharListByIndex删除失败");}voidtest_print_charlist_demo(){printCharList(pCharlist);char message[100]="test_print_charlist_demo处理完毕";assertMessageMoreTest(pCharlist->len >0,message,"test_print_charlist_demo处理失败");}//因为原有的字符串是系统创建的内存,所以不能修改,所以需要复制一份,给够空间,然后再修改staticchar*func(char* str){char* st1 =(char*)malloc(15);strcpy(st1, str);returnstrcat(st1,"1");}voidtest_forEachCharList_demo(){forEachCharList(pCharlist, func);char message[100]="test_forEachCharList_demo处理完毕";assertMessageMoreTest(pCharlist->len >0,message,"test_forEachCharList_demo处理失败");}voidtest_charListClean_demo(){charListClean(pCharlist);char message[100];sprintf(message,"charListClean清空成功,长度为%d", pCharlist->len);assertMessageMoreTest(pCharlist->len ==0,message,"charListClean清空失败");}voidtest_charListIndexOf_demo(){char*str ="hu";int i =charListIndexOf(pCharlist, str);char message[100];sprintf(message,"charListIndexOf查找成功,查找的位置为%d", i);assertMessageMoreTest(i ==-1,message ,"charListIndexOf查找失败");}voidtest_charListLastIndexOf_demo(){char*str ="hu";int i =charListLastIndexOf(pCharlist, str);char message[100];sprintf(message,"charListLastIndexOf查找成功,查找的位置为%d", i);assertMessageMoreTest(i ==-1, message ,"charListLastIndexOf查找失败");}voidtest_charListIsSorted_demo(){
    BOOL pd =charListIsSorted(pCharlist,TRUE,TRUE);char message[100];sprintf(message,"charListIsSorted判断数组是否有序 %d", pd);assertMessageMoreTest(pd, message ,"charListIsSorted判断数组是否有序失败");}voidtest_charListBinarySearch_demo(){char*str ="hu";int i =charListBinarySearch(pCharlist, str);char message[100];sprintf(message,"charListBinarySearch查找成功,查找的位置为%d", i);assertMessageMoreTest(i ==-1, message ,"charListBinarySearch查找失败");}voidtest_charListSet_demo(){char*str ="hu1111";charListSet(pCharlist, str,0);char message[100];sprintf(message,"charListSet设置成功,设置后的值为%s", pCharlist->str[0]);assertMessageMoreTest(strcmp(pCharlist->str[0],"hu1111")==0, message ,"charListSet设置失败");}voidtest_quickSortCharList_demo(){charListSort(pCharlist,TRUE);char message[100];sprintf(message,"quickSortCharList排序成功");assertMessageMoreTest( pCharlist->len >0, message ,"quickSortCharList排序失败");}voidtest_charListReverse_demo(){charListReverse(pCharlist);char message[100];sprintf(message,"charListReverse反转成功");assertMessageMoreTest( pCharlist->len >0, message ,"charListReverse反转失败");}voidtest_charListCopy_demo(){
    CharList *pCharlist1 =charListCopy(pCharlist);char message[100];sprintf(message,"charListCopy复制成功");assertMessageMoreTest( pCharlist1->len >0, message ,"charListCopy复制失败");}voidtest_charListDistinct_demo(){charListDistinct(pCharlist);char message[100];sprintf(message,"charListDistinct去重成功");assertMessageMoreTest( pCharlist->len >0, message ,"charListDistinct去重失败");}voidtest_charListMerge_demo(){
    CharList *pCharlist1 =charListCopy(pCharlist);
    CharList *merge =charListMerge(pCharlist, pCharlist1);char message[100];sprintf(message,"charListMerge合并成功,长度为%d", merge->len);assertMessageMoreTest( merge->len >0, message ,"charListMerge合并失败");}voidtest_charListDifference_demo(){
    CharList *pCharlist1 =charListCopy(pCharlist);addCharList(pCharlist,"hu1344");addCharList(pCharlist,"h222u1344");
    CharList *difference =charListDifference(pCharlist, pCharlist1);char message[100];sprintf(message,"charListDifference差集成功,长度为%d", difference->len);assertMessageMoreTest( difference->len >0, message ,"charListDifference差集失败");}voidtest_charListComplement_demo(){
    CharList *pCharlist1 =charListCopy(pCharlist);addCharList(pCharlist1,"12345");addCharList(pCharlist1,"把231");
    CharList *complement =charListComplement(pCharlist, pCharlist1);char message[100];sprintf(message,"charListComplement补集成功,长度为%d", complement->len);assertMessageMoreTest( complement->len >0, message ,"charListComplement补集失败");}voidtest_charListUnion_demo(){
    CharList *pCharlist1 =charListCopy(pCharlist);addCharList(pCharlist1,"12345");addCharList(pCharlist1,"把231");
    CharList *unionList =charListUnion(pCharlist, pCharlist1);char message[100];sprintf(message,"charListUnion并集成功,长度为%d", unionList->len);assertMessageMoreTest( unionList->len >0, message ,"charListUnion并集失败");}voidtest_charListIntersection_demo(){
    CharList *pCharlist1 =charListCopy(pCharlist);addCharList(pCharlist1,"12345");addCharList(pCharlist1,"把231");
    CharList *intersection =charListIntersection(pCharlist, pCharlist1);char message[100];sprintf(message,"charListIntersection交集成功,长度为%d", intersection->len);assertMessageMoreTest( intersection->len >0, message ,"charListIntersection交集失败");}voidtest_CharListIterator_demo(){
    CharListIterator *iterator =createCharListIterator(pCharlist);while(hasNextCharListIterator(iterator)){char*str =nextCharListIterator(iterator);printf("%s,", str);}char message[100];sprintf(message,"CharListIterator迭代器创建成功");assertMessageMoreTest( iterator!=NULL, message ,"CharListIterator迭代器创建失败");}voidtest_charlist_demo_init_method(){addTestMethodName(__FUNCTION__,"test_create_charlist_demo", TRUE,0, test_create_charlist_demo);addTestMethodName(__FUNCTION__,"test_add_charlist_demo", TRUE,1, test_add_charlist_demo);addTestMethodName(__FUNCTION__,"test_get_charlist_demo", TRUE,2, test_get_charlist_demo);addTestMethodName(__FUNCTION__,"test_del_charlist_demo", TRUE,3, test_del_charlist_demo);addTestMethodName(__FUNCTION__,"test_del_index_charlist_demo", TRUE,4, test_del_index_charlist_demo);addTestMethodName(__FUNCTION__,"test_forEachCharList_demo", TRUE,5, test_forEachCharList_demo);addTestMethodName(__FUNCTION__,"test_charListIndexOf_demo", TRUE,6, test_charListIndexOf_demo);addTestMethodName(__FUNCTION__,"test_charListLastIndexOf_demo", TRUE,7, test_charListLastIndexOf_demo);addTestMethodName(__FUNCTION__,"test_quickSortCharList_demo", TRUE,8, test_quickSortCharList_demo);addTestMethodName(__FUNCTION__,"test_charListIsSorted_demo", TRUE,9, test_charListIsSorted_demo);addTestMethodName(__FUNCTION__,"test_charListBinarySearch_demo", TRUE,10, test_charListBinarySearch_demo);addTestMethodName(__FUNCTION__,"test_charListSet_demo", TRUE,11, test_charListSet_demo);addTestMethodName(__FUNCTION__,"test_charListReverse_demo", TRUE,12, test_charListReverse_demo);addTestMethodName(__FUNCTION__,"test_charListCopy_demo", TRUE,13, test_charListCopy_demo);addTestMethodName(__FUNCTION__,"test_charListDistinct_demo", TRUE,14, test_charListDistinct_demo);addTestMethodName(__FUNCTION__,"test_charListMerge_demo", TRUE,15, test_charListMerge_demo);addTestMethodName(__FUNCTION__,"test_charListDifference_demo", TRUE,16, test_charListDifference_demo);addTestMethodName(__FUNCTION__,"test_charListComplement_demo", TRUE,17, test_charListComplement_demo);addTestMethodName(__FUNCTION__,"test_charListUnion_demo", TRUE,18, test_charListUnion_demo);addTestMethodName(__FUNCTION__,"test_charListIntersection_demo", TRUE,19, test_charListIntersection_demo);addTestMethodName(__FUNCTION__,"test_CharListIterator_demo", TRUE,20, test_CharListIterator_demo);addTestMethodName(__FUNCTION__,"test_print_charlist_demo", TRUE,99, test_print_charlist_demo);addTestMethodName(__FUNCTION__,"test_charListClean_demo", TRUE,100, test_charListClean_demo);}

验证

#include<stdio.h>#include"unittest/testfactory.h"#include"./unittest//testdemo/test_verification_demo.h"#include"./unittest/testdemo/test_verification_demo1.h"#include"./unittest/testdemo/test_charlist_demo.h"staticvoidtest_init(){//初始化测试组addTestGroup("verification_demo_initMethod",FALSE,0,verification_demo_initMethod);addTestGroup("verification_demo1_initMethod",FALSE,1,verification_demo1_initMethod);addTestGroup("test_charlist_demo_init_method",TRUE,2,test_charlist_demo_init_method);}staticvoidtest_run(){testMain(test_init);//初始化测试//运行全部的测试方法//    test_Run_GroupAll_MethodAlL();test_Run_Core_Group_ALL();//运行全部的测试组//    test_Run_Group("test_charlist_demo_init_method"); //运行指定测试组//    test_Run_Method("test_print_charlist_demo"); //运行指定测试方法}intmain(){test_run();return(0);}

在这里插入图片描述

现在我就能随心所欲的测试了,想测试那个方法就测试那个方法,方法之间还可以联动测试,模块和模块还可以交互测试,等等

在这里插入图片描述
点赞 -收藏-关注-便于以后复习和收到最新内容有其他问题在评论区讨论-或者私信我-收到会在第一时间回复在本博客学习的技术不得以任何方式直接或者间接的从事违反中华人民共和国法律,内容仅供学习、交流与参考 免责声明:本文部分素材来源于网络,版权归原创者所有,如存在文章/图片/音视频等使用不当的情况,请随时私信联系我、以迅速采取适当措施,避免给双方造成不必要的经济损失。感谢,配合,希望我的努力对你有帮助^_^


本文转载自: https://blog.csdn.net/weixin_45203607/article/details/126660961
版权归原作者 胡安民 所有, 如有侵权,请联系我们删除。

“C语言-单元测试(自研)”的评论:

还没有评论