Cunit (white box unit test based on Linux)

Source: Internet
Author: User
Tags assert xsl

Cunit is a framework for unit testing of programs written in the C language, and online documentation says it is linked to the user's test code as a static link library.

It provides a concise framework for building test architectures and provides a rich set of assertions (assertion) to test common data types. In addition, it provides a

Many different structures to run test cases and report test results.

(1) Architecture of the Cunit

It can be seen that Cunit is also organized, mainly in several roles, Registry,suite and test methods. This organizational relationship can be realized through the following example.
According to official documentation, the main steps to using Cunit are:
1) Write Functions for tests (and suite init/cleanup if necessary).
2) Initialize the test registry-cu_initialize_registry ()
3) Add Suites to the Test registry-cu_add_suite ()
4) ADD tests to the Suites-cu_add_test ()
5) Run tests using an appropriate interface, e.g. cu_console_run_tests
6) Cleanup the test registry-cu_cleanup_registry

(2) Test mode

The following are four test modes:
1 automated Output to XML file            Non-interactive
2 basic      Flexible programming         Interface non-interactive 
3 console    Console interface (ANSI C)       interactive 
4 curses     graphical Interface (Unix)      Interactive
The first mode is to output the results to an XML document, making it easy to generate reports. The second mode is to display the test results in standard output after each run, and the test result data cannot be persisted. The third mode is the console mode, can be human-computer interaction, the first two modes are non-interactive. The fourth type is only used in UNIX.

(3) Basic process of testing
1) Write the Unit test function (write the Init/cleanup function of suite if necessary). Write functions for tests (and suite init/cleanup if necessary).
2) Call the function cu_initialize_registry () to initialize the test registration unit (testing registry). Initialize the test registry-cu_initialize_registry ()
3) Call the function Cu_add_suite () to add the test package (suite) to the test registration unit (testing Registry). ADD Suites to the Test registry-cu_add_suite ()
4) Call the function cu_add_test () to add the test case to the test package (suite). ADD tests to the Suites-cu_add_test ()
5) Use the appropriate interface to run the test case. Run tests using an appropriate interface, e.g. cu_console_run_tests
6) Call the function Cu_cleanup_registry clear the test registration unit (testing Registry). Cleanup the test registry-cu_cleanup_registry ()

Write a function that has two simple functions, and then write testcase to test it.

The main documents are:
1) Strformat.h: interface file for string function functions
2) Strformat.c: implementation of string function function
3) testcase.c: Test case and Cunit operating environment
4) Makefile:

Go directly to the code, strformat.h.

#ifndef _strformat_h#define _strformat_htypedef char * string; int String_lenth (string word), string to_upper (string word), string add_str (String word1, String word2), #endif

Strformat.c

#include <assert.h> #include <ctype.h> #include <errno.h> #include <limits.h> #include < string.h> #include <stdarg.h> #include <stdlib.h> #include <stdio.h> #include "strformat.h"/***** Function Name: string addition ******************************** /string add_str (String word1, String word2) {return (strcat (word1, Word2));} /************************************************************************** function Name: Converts a string to uppercase format ********************    /string To_upper (string word) {int i;        for (i = 0;word[i]! = ' word[i '; i++) {if (word[i]< ' z ' && word[i]> ' a ') {]-= 32;    }} return word; }/************************************************************************** function Name: string length ************************* /int String_lenth (string word){int i; for (i = 0; Word[i]! = ' + '; i++) {} return i;}

Testcase.c

/* TESTCASE.C---* * filename:testcase.c * Description: Test Example *//* Commentary: * The current file is used to define test methods, Suite, and registry information, if the test method has Changes, you only need to modify the current file. * First step: Write the code of the test function, and suggest to prefix "Test_". * Step two: Classify the test methods into an array of similar functional test methods in order to assign them to a suite * Third step: Create a suite that can generate multiple test suite by function or module, * Fourth step: Write the total calling method of the test method, Addtests () To unify the startup test method. *//* Code: */#include <assert.h> #include <ctype.h> #include <errno.h> #include <limits.h># Include <string.h> #include <stdarg.h> #include <stdlib.h> #include <stdio.h> #include < cunit/basic.h> #include <CUnit/Console.h> #include <CUnit/CUnit.h> #include <cunit/testdb.h># Include "Strformat.h"/************************************************************************** function name: Test string_ Lenth () method **************************************************************************/void test_string_lenth (void    {String test = "Hello";    int len = string_lenth (test); Cu_assert_equal (len,5);} /*********************************************************Function Name: Test method To_upper () **************************************************************************    /void test_to_upper (void) {char test[] = "Hello"; Cu_assert_string_equal (To_upper (Test), "HELLO");} /************************************************************************** function Name: Test method Add_str () *****************    /void test_add_str (void) {char test1[] = "hello!";    Char test2[] = "MGC"; Cu_assert_string_equal (Add_str (Test1,test2), "hello! MGC "); /************************************************************************** Array Name: Package multiple test methods into groups, To assign to a suite feature description: Each suite can have one or more test methods, specified in Cu_testinfo array form ******************************************************* Cu_testinfo is a cunit built-in structure that includes test methods and description information Cu_testinfo testcase[] = {"Test_for_lenth:", Test_ String_lenth}, {"Test_for_add:", Test_add_str}, Cu_test_info_null}; Cu_testinfo testcase2[] = {{"Test for Upper:", test_to_upper}, Cu_test_info_null};/************************************************************************** Function Name: Suite initialization Process function Description: input parameter: return: **************************************************************************/int Suite_success_init (void) {return 0;} /************************************************************************** function Name: Suite cleanup process to restore status so that the results do not affect the next run * * /int Suite_success_clean (void) {return 0;} Define a suite array, including multiple suite, each of which includes several test methods. Cu_suiteinfo suites[] = {{"TestSuite1", suite_success_init,suite_success_clean,testcase}, {"Testsuite2", Suite_succe SS_INIT,SUITE_SUCCESS_CLEAN,TESTCASE2}, cu_suite_info_null};/************************************************** Function Name: The calling total interface of the test class *************************************************************************    */void addtests () {assert (NULL! = Cu_get_registry ()); ASSERT (!    Cu_is_test_running ()); if (cue_success! = Cu_register_suites (suites)) {EXIt (exit_failure); }}/************************************************************************** function Description: Run Test entry *********************** /int Runtest () {if (Cu_initialize_registry ()) {FPR                intf (stderr, "Initialization of Test Registry failed.");        Exit (Exit_failure);                }else{addtests ();                /**** Automated Mode ***************** cu_set_output_filename ("Testmax");                Cu_list_tests_to_file ();                Cu_automated_run_tests ();                //***** Basice Mode *******************                Cu_basic_set_mode (Cu_brm_verbose);                Cu_basic_run_tests (); //*****console Mode ******************** Cu_console_r                Un_tests ();           //************************************/     Cu_cleanup_registry ();        return Cu_get_error (); }}/************************************************************************** Function Description: Test class Main Method ***********************    /int Main (int argc, char * argv[]) {return runtest (); }

Code: Makefile

iinc=-i/usr/local/include/cunitlib=-l/usr/local/lib/all:  strformat.c testcase.c    -O Test $ (INC) $ (LIB)  $^-lcunit-static

Note:
1) Cunit installation is simple, from the official address downloaded from the source code, in the local execution
./configure
Make
sudo make install
After successful installation, the associated library and header files are installed to the default path. Add options at compile time:
-i/usr/local/include/cunit
-l/usr/local/lib/
Just like in the makefile.

Let's take a look at several common operating modes of Cunit
1) Automated Mode
The testcase.c in the 156~159 code to release comments, at this point is run in automated mode, this module does not have the ability to interact, directly generate the XML format of the report, make, and then run, in the current directory to generate two of reports
Testmax-listing.xml and Testmax-results.xml (the former is a list of test cases, which are test results for test cases), but these two files are not directly viewable, to view these two files, You need to use the following XSL and DTD files: Cunit-list.dtd and cunit-list.xsl are used to parse the list file, Cunit-run.dtd and cunit-run.xsl are used to parse the result file. These four files are available in the Cunit package, and are installed in the/home/lirui/local/share/cunit directory after installation in the $ (PREFIX)/share/cunit directory. Before viewing the results, you need to put these six files: Testmax-listing.xml, Testmax-results.xml, Cunit-list.dtd, cunit-list.xsl, CUNIT-RUN.DTD, cunit-run.xsl copy to a directory, and then open the two result XML file with a browser.
As shown in the following:

2) Console Mode
Comment out the other mode code in TESTCASE.C, release 168 lines of code, then convert to console mode. Console mode supports interaction, such as support for running, viewing errors, and so on, as shown in the following:

As you can see, enter R to run, enter F to view the error case, enter Q to exit

This model is very practical in practice.

3) Basic Mode
In testcase.c the code of the other mode commented out, put in the 163~164 line code, then converted to basic mode, this is not interactive, directly print out the results of the operation.

It can be seen that this model is also relatively simple and fast


2. Use Cunit in two different environments to perform unit tests on the above example.

2.1 Under Windows XP, set up Cunit in VC 6 to perform unit testing.
(1) Build the link static library CUnit.lib yourself.
Download Cunit-2.1-0-src.zip, unzip, in the Cunit-2.1-0/cunit directory, with VC 6.0 open the project file CUNIT.DSP, there is a hint, said no workspace file found, will not be ignored, directly determined. Then in the currently open project, click "FileView", expand the file tree structure, any click on a file open, and then click on the top toolbar "compile" and "link" in the Cunit-2.1-0/cunit directory to produce CUnit.lib.
(2) Create a new WIN32 console application project named "Test_cuit" in VC 6.0 to include the files in the above example.
(3) Download Cunit-2.1-0-winlib.zip, unzip, unzip the directory cunit-2.1-0 copy to the current project directory.
(4) Copy the CUnit.lib leaf to the current project directory and "Link", "Project", "Settings ...", "Object/library modules" Add CUnit.lib at the end of the content, separated by a blank space from the previous static library file, and then click "OK".
(5) in the "Test_cuit" project, click "Compile", "link" and "Run" on the top toolbar to see the console interface. Enter the appropriate operation symbol for the corresponding operation, no longer detailed.

Note: The part commented out in the Addtestmainmodule () function of TESTMAINMODULE.C is the first Test mode "automated Output to XML file", and the default mode is the third console mode. Commenting out the console mode and opening the first Test mode, the runtime will have three XML files in the current directory: Cunit-memory-dump.xml,testmax-listing.xml,testmax-results.xml. You can see the results of the test report by copying the three files to the directory Cunit-2.1-0/share/cunit and then opening the latter two XML files with a browser.

2.2 Under Linux, use Cunit for unit testing.
1. Compile cunit, compile, header file directory in/root/local/include/cunit, static library file under/root/local/lib/.
(1) Log in with the root user and download the cunit-2.1-0-src.tar.gz.
(2) TAR-ZXVF cunit-2.1-0-src.tar.gz
(3) CD cunit-2.1-0
(4)./configure--prefix= $HOME/local
(5) Make
(6) Make install
2. Write a makefile file and put it in the source file directory with the following contents:

    1. Inc=-i/root/local/include
    2. Lib=-l/root/local/lib
    3. ALL:MAINMODULE.C testmainmodule.c cunitruntest.c
    4. GCC $^-o test $ (INC) $ (LIB)-lcunit-lcurses-static
    5. Clean
    6. RM-RF Test
3. Execute the Make command in the source file directory.

4. Run the./test to see the console command interface.


3. About the use of assertions
Cunit provides a series of assertions to test the logic conditions, and the success or failure of these assertions is tracked by the Cunit Unit test framework and can be seen at the end of the unit test. Each assertion tests a logical condition. If you select Xxx_fatal these assertions, meaning that the unit test case no longer executes after the assertion fails, the assertion version with "FATAL" needs to be used with caution. Assertions are contained in the header file "Cunit/cunit.h". Now extract its assertion statement from the Cunit document description.

CU_ASSERT(int expression)
CU_ASSERT_FATAL(int expression)
CU_TEST(int expression)
CU_TEST_FATAL(int expression)
Assert that expression is TRUE (Non-zero)
CU_ASSERT_TRUE(value)
CU_ASSERT_TRUE_FATAL(value)
Assert that value isTRUE (non-zero)
CU_ASSERT_FALSE(value)
CU_ASSERT_FALSE_FATAL(value)
Assert that value is FALSE (zero)
CU_ASSERT_EQUAL(actual, expected)
CU_ASSERT_EQUAL_FATAL(actual, expected)
Assert that actual = = expected
CU_ASSERT_NOT_EQUAL(actual, expected))
CU_ASSERT_NOT_EQUAL_FATAL(actual, expected)
Assert that actual ! = expected
CU_ASSERT_PTR_EQUAL(actual, expected)
CU_ASSERT_PTR_EQUAL_FATAL(actual, expected)
Assert that pointers actual = = expected
CU_ASSERT_PTR_NOT_EQUAL(actual, expected)
CU_ASSERT_PTR_NOT_EQUAL_FATAL(actual, expected)
Assert that pointers actual ! = expected
CU_ASSERT_PTR_NULL(value)
CU_ASSERT_PTR_NULL_FATAL(value)
Assert that pointer value = = NULL
CU_ASSERT_PTR_NOT_NULL(value)
CU_ASSERT_PTR_NOT_NULL_FATAL(value)
Assert that pointer value ! = NULL
CU_ASSERT_STRING_EQUAL(actual, expected)
CU_ASSERT_STRING_EQUAL_FATAL(actual, expected)
Assert that strings actual and expected is equivalent
CU_ASSERT_STRING_NOT_EQUAL(actual, expected)
CU_ASSERT_STRING_NOT_EQUAL_FATAL(actual, expected)
Assert that strings actual and expected differ
CU_ASSERT_NSTRING_EQUAL(actual, expected, count)
CU_ASSERT_NSTRING_EQUAL_FATAL(actual, expected, count)
Assert that 1st Count chars of actual and expected is the same
CU_ASSERT_NSTRING_NOT_EQUAL(actual, expected, count)
CU_ASSERT_NSTRING_NOT_EQUAL_FATAL(actual, expected, count)
Assert that 1st Count chars of actual and expected differ
CU_ASSERT_DOUBLE_EQUAL(actual, expected, granularity)
CU_ASSERT_DOUBLE_EQUAL_FATAL(actual, expected, granularity)
Assert that | actual - expected| <= | Granularity|
The Math library must be linked on for this assertion.
CU_ASSERT_DOUBLE_NOT_EQUAL(actual, expected, granularity)
CU_ASSERT_DOUBLE_NOT_EQUAL_FATAL(actual, expected, granularity)
Assert that | actual - expected| > | Granularity|
The Math library must be linked on for this assertion.
CU_PASS(message) Register a passing assertion with the specified message. No logical test is performed.
CU_FAIL(message)
CU_FAIL_FATAL(message)
Register a failed assertion with the specified message. No logical test is performed

Two versions of the source code are given for download. Note: The source files under VC6.0 cannot be used directly under Linux, and if you want to use them, you are prompted to add a newline character at the end of each source file.

Example of "1" VC 6.0

Example of "2" Linux (Unable to upload. tar.gz formatted files)

Cunit (white box unit test based on Linux)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.