[置顶] C语言单元测试框架

unitest.h

 

/******************************************************************************

 *                                                                            *

 * This program is distributed in the hope that it will be useful, but        *

 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY *

 * or FITNESS FOR A PARTICULAR PURPOSE. This file and program are licensed    *

 * under the GNU Lesser General Public License Version 3, 29 June 2007.       *

 * The complete license can be accessed from the following location:          *

 * http://opensource.org/licenses/lgpl-3.0.html                               *

 *                                                                            *

 * Author: Yun Li ([email protected])                                      *

 *   Date: 03/06/2010                                                         *

 * Author: Gavin Ding ([email protected] / [email protected])        *

 *   Date: 07/07/2013                                                         * 

 ******************************************************************************/



/******************************************************************************

  REVISION HISTORY

  ================

 

  Date         Version       Name              Description

  ----------   ------------  ----------------  --------------------------------

  03/17/2013   V001.000.000  Gavin Ding        rewrite this file

  ----------   ------------  ----------------  --------------------------------

  

  Date         Version       Name              Description

  ----------   ------------  ----------------  --------------------------------

  07/07/2013   V001.001.000  Gavin Ding        make it more useful

  ----------   ------------  ----------------  --------------------------------



 ******************************************************************************/



#ifndef __UNITEST_H

#define __UNITEST_H



#include <stdio.h>

#include <string.h>



static int g_case_total     = 0;

static int g_case_succeeded = 0;

static int g_case_failed    = 0;



#ifndef NULL

#define NULL ((void*)0)

#endif



#define INTERNAL_USE_ONLY_SUCCEEDED(_a, _b, _oper) \

    printf("    Expected: \""#_a"\" "#_oper" \""#_b"\"\n      Result: Succeeded\n")

#define INTERNAL_USE_ONLY_FAILED(_a, _b, _oper) \

    printf("    Expected: \""#_a"\" "#_oper" \""#_b"\"\n (X)  Result: Failed\n")    

#define INTERNAL_USE_ONLY_CASE_SHOW() \

    printf("Case %d =====>\n", g_case_total); \

    printf("    Location: %s:%d\n", __FILE__, __LINE__); \



#define UNITEST_ERROR(_string) do { \

    printf("Error: "#_string"\n"); \

    return -1;\

} while (0)



#define UNITEST_EQUALS(_a, _b) do { \

    g_case_total++; \

    INTERNAL_USE_ONLY_CASE_SHOW(); \

    if ((_a) == (_b)) { \

        INTERNAL_USE_ONLY_SUCCEEDED(_a, _b, ==); \

        g_case_succeeded++; \

    } \

    else { \

        INTERNAL_USE_ONLY_FAILED(_a, _b, ==); \

        g_case_failed++; \

    } \

    printf("\n"); \

} while (0)



#define UNITEST_DIFFERS(_a, _b) do { \

    g_case_total++; \

    INTERNAL_USE_ONLY_CASE_SHOW(); \

    if ((_a) == (_b)) { \

        INTERNAL_USE_ONLY_FAILED(_a, _b, !=); \

        g_case_failed++; \

    } \

    else { \

        INTERNAL_USE_ONLY_SUCCEEDED(_a, _b, !=); \

        g_case_succeeded++; \

    } \

    printf("\n"); \

} while (0)



#define UNITEST_LESS_THAN(_a, _b) do { \

    g_case_total++; \

    INTERNAL_USE_ONLY_CASE_SHOW(); \

    if ((_a) < (_b)) { \

        INTERNAL_USE_ONLY_SUCCEEDED(_a, _b, <); \

        g_case_succeeded ++; \

    } \

    else { \

        INTERNAL_USE_ONLY_FAILED(_a, _b, <); \

        g_case_failed++; \

    } \

    printf("\n"); \

} while (0)



#define UNITEST_LESS_THAN_EQUALS(_a, _b) do { \

    g_case_total++; \

    INTERNAL_USE_ONLY_CASE_SHOW(); \

    if ((_a) <= (_b)) { \

        INTERNAL_USE_ONLY_SUCCEEDED(_a, _b, <=); \

        g_case_succeeded++; \

    } \

    else { \

        INTERNAL_USE_ONLY_FAILED(_a, _b, <=); \

        g_case_failed++; \

    } \

    printf("\n"); \

} while (0)



#define UNITEST_GREATER_THAN(_a, _b) do { \

    g_case_total++; \

    INTERNAL_USE_ONLY_CASE_SHOW(); \

    if ((_a) > (_b)) { \

        INTERNAL_USE_ONLY_SUCCEEDED(_a, _b, >); \

        g_case_succeeded++; \

    } \

    else { \

        INTERNAL_USE_ONLY_FAILED(_a, _b, >); \

        g_case_failed++; \

    } \

    printf("\n"); \

} while (0)



#define UNITEST_GREATER_THAN_EQUALS(_a, _b) do { \

    g_case_total++; \

    INTERNAL_USE_ONLY_CASE_SHOW(); \

    if ((_a) >= (_b)) { \

        INTERNAL_USE_ONLY_SUCCEEDED(_a, _b, >=); \

        g_case_succeeded++; \

    } \

    else { \

        INTERNAL_USE_ONLY_FAILED(_a, _b, >=); \

        g_case_failed++; \

    } \

    printf("\n"); \

} while (0)



#define UNITEST_STR_EQUALS(_a, _b) do { \

    g_case_total++; \

    INTERNAL_USE_ONLY_CASE_SHOW(); \

    if ( NULL == (_a) || NULL == (_b) ) { \

        UNITEST_ERROR(ptr should not be NULL); \

    } \

    if ( !strcmp((_a), (_b)) ) { \

        INTERNAL_USE_ONLY_SUCCEEDED(_a, _b, ==); \

        g_case_succeeded++; \

    } \

    else { \

        INTERNAL_USE_ONLY_FAILED(_a, _b, ==); \

        g_case_failed++; \

    } \

    printf("\n"); \

} while (0)



#define UNITEST_STR_DIFFERS(_a, _b) do { \

    g_case_total++; \

    INTERNAL_USE_ONLY_CASE_SHOW(); \

    if ( NULL == (_a) || NULL == (_b) ) { \

        UNITEST_ERROR(ptr should not be NULL); \

    } \

    if ( !strcmp((_a), (_b)) ) { \

        INTERNAL_USE_ONLY_FAILED(_a, _b, !=); \

        g_case_failed++; \

    } \

    else { \

        INTERNAL_USE_ONLY_SUCCEEDED(_a, _b, !=); \

        g_case_succeeded++; \

    } \

    printf("\n"); \

} while (0)



#define UNITEST_MEM_EQUALS(_a, _b, _len) do { \

    g_case_total++; \

    INTERNAL_USE_ONLY_CASE_SHOW(); \

    if ( NULL == (_a) || NULL == (_b) ) { \

        UNITEST_ERROR(ptr should not be NULL); \

    } \

    if ( (_len) <= 0 ) { \

        UNITEST_ERROR(mem len should be positive); \

    } \ 

    if ( !memcmp((void*)(_a),(void*)(_b), (int)(_len)) ) { \

        INTERNAL_USE_ONLY_SUCCEEDED(_a, _b, ==); \

        g_case_succeeded++; \

    } \

    else { \

        INTERNAL_USE_ONLY_FAILED(_a, _b, ==); \

        g_case_failed++; \

    } \

    printf("\n"); \

} while (0)



#define UNITEST_MEM_DIFFERS(_a, _b, _len) do { \

    g_case_total++; \

    INTERNAL_USE_ONLY_CASE_SHOW(); \  

    if ( NULL == (_a) || NULL == (_b) ) { \

        UNITEST_ERROR(ptr should not be NULL); \

    } \

    if ( (_len) <= 0 ) { \

        UNITEST_ERROR(mem len should be positive); \

    } \

    if ( !memcmp((void*)(_a), (void*)(_b), (int)(_len)) ) { \

        INTERNAL_USE_ONLY_FAILED(_a, _b, !=); \

        g_case_failed++; \

    } \

    else { \

        INTERNAL_USE_ONLY_SUCCEEDED(_a, _b, !=); \

        g_case_succeeded++; \

    } \

    printf("\n"); \

} while (0)



static void unitest_bar()

{

    printf("********************************************************\n"); 

    printf("*                      Unit Test                       *\n");

    printf("********************************************************\n");

    printf("\n");

}



static int unitest_report()

{

    printf("\n");

    printf("********************************************************\n"); 

    printf("*                     Test Report                      *\n");

    printf("********************************************************\n");

    

    if (0 == g_case_total) {

        printf("No test case is run\n");

        goto pass;

    }

    printf("    Total: %d\n", g_case_total);

    printf("Succeeded: %d (%d%%)\n", g_case_succeeded, g_case_succeeded * 100 / g_case_total);

    printf("********************************************************\n"); 

    printf("\n");



    if (g_case_total != g_case_succeeded) {

        printf("\n");

        printf(":-( Failed\n");

        printf("\n");

        return -1;

    }



pass:    

    printf("\n");

    printf(":-) Passed\n");

    printf("\n");



    return 0;

}



#ifndef HAVE_MAIN

extern int unitest_main(int _argc, char *_argv[]);



int main(int _argc, char *_argv[])

{

    unitest_bar();

    unitest_main(_argc, _argv);

    return unitest_report();

}

#endif  /* end of HAVE_MAIN */



#endif  /* end of __UNITEST_H */


unitest_demo.c

 

/******************************************************************************

 *                                                                            *

 * This program is distributed in the hope that it will be useful, but        *

 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY *

 * or FITNESS FOR A PARTICULAR PURPOSE. This file and program are licensed    *

 * under the GNU Lesser General Public License Version 3, 29 June 2007.       *

 * The complete license can be accessed from the following location:          *

 * http://opensource.org/licenses/lgpl-3.0.html                               *

 *                                                                            *

 * Author: Gavin Ding ([email protected] / [email protected])        *

 *   Date: 07/07/2013                                                         * 

 *                                                                            *

 ******************************************************************************/



/******************************************************************************

  REVISION HISTORY

  ================

  

  Date     Version  Name          Description

  -------- -------  ------------  --------------------------------------------



  -------- -------  ------------  --------------------------------------------



 ******************************************************************************/

#include "unitest.h"

#include <stdlib.h>



#define UNUSED(param) ((param) = (param))



int unitest_main (int argc, char *argv[])

{ 

	char *str1 = "YT";

	char *str2 = "HW";

	char *str3 = "HW";

	void *p1   = NULL;

	void *p2   = NULL;



    UNUSED(argc);

    UNUSED(argv);

    

    UNITEST_EQUALS(87, 87);



	UNITEST_DIFFERS(10, 13);



	UNITEST_LESS_THAN(41, 70);



	UNITEST_LESS_THAN_EQUALS(8, 8);

	UNITEST_LESS_THAN_EQUALS(7, 8);



	UNITEST_GREATER_THAN(70, 41);



	UNITEST_GREATER_THAN_EQUALS(8, 8);

	UNITEST_GREATER_THAN_EQUALS(8, 7);



	UNITEST_STR_EQUALS(str2, str3);



	UNITEST_STR_DIFFERS(str1, str2);

    

	p1 = malloc(10);

	memset(p1, 2, 10);



	p2 = malloc(10);

	memset(p2, 2, 10);



	UNITEST_MEM_EQUALS(p1, p2, 10);



	memset(p2, 5, 10);

	UNITEST_MEM_DIFFERS(p1, p2, 10);



	free(p1);

	p1 = NULL;



	free(p2);

	p2 = NULL;



	return 0;

}


unitest_demo.result

 

 

./unitest/unitest_demo.exe

********************************************************

*                      Unit Test                       *

********************************************************



Case 1 =====>

    Location: unitest_demo.c:41

    Expected: "87" == "87"

      Result: Succeeded



Case 2 =====>

    Location: unitest_demo.c:43

    Expected: "10" != "13"

      Result: Succeeded



Case 3 =====>

    Location: unitest_demo.c:45

    Expected: "41" < "70"

      Result: Succeeded



Case 4 =====>

    Location: unitest_demo.c:47

    Expected: "8" <= "8"

      Result: Succeeded



Case 5 =====>

    Location: unitest_demo.c:48

    Expected: "7" <= "8"

      Result: Succeeded



Case 6 =====>

    Location: unitest_demo.c:50

    Expected: "70" > "41"

      Result: Succeeded



Case 7 =====>

    Location: unitest_demo.c:52

    Expected: "8" >= "8"

      Result: Succeeded



Case 8 =====>

    Location: unitest_demo.c:53

    Expected: "8" >= "7"

      Result: Succeeded



Case 9 =====>

    Location: unitest_demo.c:55

    Expected: "str2" == "str3"

      Result: Succeeded



Case 10 =====>

    Location: unitest_demo.c:57

    Expected: "str1" != "str2"

      Result: Succeeded



Case 11 =====>

    Location: unitest_demo.c:65

    Expected: "p1" == "p2"

      Result: Succeeded



Case 12 =====>

    Location: unitest_demo.c:68

    Expected: "p1" != "p2"

      Result: Succeeded





********************************************************

*                     Test Report                      *

********************************************************

    Total: 12

Succeeded: 12 (100%)

********************************************************





:-) Passed


 

 

你可能感兴趣的:(单元测试)