Problem solving during unit testing

Source: Internet
Author: User

Recently, I used to perform unit tests. However, at that time, I wrote a function and tested it myself. Therefore, I am very familiar with the logic and data structure of the function, but now it's for reading other people'sCodeAnd then perform unit tests. I should focus on the functions of this module if I do unit tests, you do not need to know the processing details of the functions of other modules encountered in the tested functions. You just need to pile up and call the functions for them, this unit test is actually the testing framework of each module's developer, and no one knows how to pile up the function, which makes it quite painful for me to do it, but we still need to solve the problem, so now let's record the problems we have solved.

First of all, I know that the gtest tool I have used is an open-source software and supports function piling. So I will first collect relevant information:

Gtest profiling (draft)
++ G Test
Version: 1.5.0
* 1) how to run the test *

# Define run_all_tests ()\
(: Testing: unittest: getinstance ()-> Run ())
------------------------
Unittestimpl: runalltests ()
Test_cases _. foreach (testcase: runtestcase)
Testcase: runtestcase
Static void runtestcase (testcase * test_case) {test_case-> Run ();}
Testcase: Run ()
Test_info_list _-> foreach (internal: testinfoimpl: runtest );
Static void runtest (testinfo * test_info) {test_info-> impl ()-> Run ();}
Testinfoimpl: Run ()
Test = factory _-> createtest ()
Test-> Run ();
Test: Run ()
Testbody ();
------------------------
1. unittest Singleton, the overall test, including test environment information, current execution status, and so on.

2. The implementer of the specific functions in unittestimpl unittest.

3. Test the test object written by ourselves, or the test object after being expanded using macros such as test and test_f, manages the pre-and post-test events and the specific Execution Code testbody.

4. testcase test case object. It manages pre-and post-events based on testcase and manages multiple internal testinfo instances.

5. testinfo manages the basic information of the test case, including the method for creating the test object.

6. The implementer of the specific functions in testinfoimpl testinfo.

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

* 2) how to generate a test *
---------------
Test (footest, demo)
{
Expect_eq (1, 1 );
}
---------------
Expand
---------------
Class footest_demo_test: public: Testing: Test
{
Public:
Footest_demo_test (){}
PRIVATE:
Virtual void testbody ();
Static: Testing: testinfo * const test_info _;
Footest_demo_test (const footest_demo_test &);
Void operator = (const footest_demo_test &);
};

: Testing: testinfo * const footest_demo_test
: Test_info _ =
: Testing: Internal: makeandregistertestinfo (
"Footest", "Demo ","","",
(: Testing: Internal: gettesttypeid ()),
: Testing: Test: setuptestcase,
: Testing: Test: teardowntestcase,
New: Testing: Internal: testfactoryimpl <footest_demo_test> );

Void footest_demo_test: testbody ()
{
Switch (0)
Case 0:
If (const: Testing: assertionresult
Gtest_ar =
(: Testing: Internal: eqhelper <(sizeof (: Testing: Internal: isnullliteralhelper (1) = 1) >:: compare ("1 ", "1", 1, 1 )))
;
Else
: Testing: Internal: asserthelper (
: Testing: tprt_nonfatal_failure,
". \ Gtest_demo.cpp ",
9,
Gtest_ar.failure_message ()
) =: Testing: Message ();
}
After expansion, we observe that:

1. After the test macro is expanded, it is a class inherited from testing: test.

2. The test code we wrote in the test macro is actually put into the testbody method of the class.

3. Call makeandregistertestinfo through the static variable test_info _ to register the test case.

++ Test info

We can see that a testinfo object is created above, and this object is registered through addtestinfo. What is the testinfo object?

The testinfo object is mainly used to include the following information:

1. Test Case name (testcase name)

2. Test name)

3. Whether the case needs to be executed

4. The function pointer used to create the test object during execution.

5. Test Results

We also see that a very important parameter in the testinfo constructor is the factory object, which is mainly responsible for creating the test object when running the test case. We can see that the factory in the above example is:

New: Testing: Internal: testfactoryimpl <footest_demo_test>
We understand that the test object is the object (footest_demo_test) of the class after the test macro is expanded. Let's look at the implementation of testfactoryimpl:

Template <class testclass>
Class testfactoryimpl: Public testfactorybase {
Public:
Virtual Test * createtest () {return New testclass ;}

};

++ Test Factory impl

Template <class testclass>
Class testfactoryimpl: Public testfactorybase {
Public:
Virtual Test * createtest () {return New testclass ;}
};

++ Make and register test info

// Create a testinfo object and register it with Google test;
// Return the created testinfo object
//
// Parameters:
//
// Test_case_name: name of the test case
// Name: name of the test
// Test_case_comment: Comment of the test case
// Comment: Test comments
// Fixture_class_id: ID of the test fixture class
// Set_up_tc: Address of the setuptestcases function of the event Function
// Tear_down_tc: Address of the event function teardowntestcases
// Factory: A factory object used to create a test object)
Testinfo * makeandregistertestinfo (
Const char * test_case_name, const char * Name,
Const char * test_case_comment, const char * comment,
Typeid fixture_class_id,
Setuptestcasefunc set_up_tc,
Teardowntestcasefunc tear_down_tc,
Testfactorybase * factory ){
Testinfo * const test_info =
New testinfo (test_case_name, name, test_case_comment, comment,
Fixture_class_id, factory );
Getunittestimpl ()-> addtestinfo (set_up_tc, tear_down_tc, test_info );
Return test_info;
}

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

* 3) How to Use gtest *

++ How to use gtest

Gtest Introduction

Gtest is simple and easy to use during recent tests. It is a very good unit test framework. Let's briefly introduce how to use it.
I. Installation
Official Website: http://code.google.com/p/googletest/
1. download the latest version: gtest-1.4.0.tar.gz
2, extract and enter the gtest-1.4.0
3. Run./configure make install (The sudo permission is required, or you can specify the installation directory by yourself)
4. Go to the root directory, Edit. bashrc, and add the library file path export LD_LIBRARY_PATH =/usr/local/lib: $ LD_LIBRARY_PATH
(Compile and TestProgramYou can find the generated gtest library file)
 
Ii. Call
1. Add # include <gtest/gtest. h> when writing a test program.
2. Add the following content when compiling the test program-LDL-lgtest-I/usr/local/include (load the gtest header file)
 
Code:

# Include <iostream>

# Include <cstdlib>

Using namespace STD;

# Include <gtest/gtest. h>

Int fun (INT Val)

{

Return val;

}

// Test case

Test (test, testfun)

{

// Check whether the return value of the function is equal to the given value.

Expect_eq (10, fun (10 ));

Expect_eq (9, fun (10 ));

}

Int main (INT argc, char * argv [])

{

// Initialization

Testing: initgoogletest (& argc, argv );

// Run all test cases

Run_all_tests ();

System ("pause ");

Return 0;

}

Macros and events

Assert macros can be understood as two types: assert and reverse CT. When the checkpoint fails, the assert Macro will exit the current function, and the assert series will continue to execute.

Gtest defines a variety of macros for different needs, including macros for boolean type, macros for logical checks for numeric type, and macros for string. There are also some macros used for exception checks in special cases.

The main function of macros is to check whether all tested functions work as expected.

Event mechanism: enables us to perform operations before and after the case. Events are generally divided into three types:

1. Global, before and after all cases.

2. testsuit level, before the first case in a batch of cases, after the last case is executed.

3. testcase level, before and after each testcase.

Event implementation

4. Write a global event class that inherits the test: Environment class and implements setup and teardown. Setup is executed before execution of all cases, and teardown is executed after execution of all cases.

5. testsuit writes a class that inherits testing: Test and implements two static methods, setuptestcase, which is executed before the first testcase. Teardowntestcase is executed after the last testcase. When writing the test case, we need to use the test_f macro. The first parameter is used, and the name of the derived class is used.

6. testcase writes a class, inherits testing: test, and then overwrites the setup and teardown methods. The setup method is executed before each testcase, And the teardown method is executed after each testcase. You also need to use the test_f Macro when writing test cases.
7.
Iv. Test results of the program
 
Gtest gives the difference between the expected value and the actual value for each failed case and the name of the failed case.
 
V. gtest assertions
Boolean check
Fatal assertion
Nonfatal assertion
Verifies
Assert_true (condition );
Expect_true (condition );
Conditionis true
Assert_false (condition );
Expect_false (condition );
Conditionis false
Numeric data check

fatal assertion
nonfatal assertion
verifies
assert_eq (expected, actual);
expect_eq (expected, actual );
expected = actual
assert_ne (val1, val2);
expect_ne (val1, val2);
val1! = Val2
assert_lt (val1, val2);
expect_lt (val1, val2);
val1 assert_le (val1, val2 );
expect_le (val1, val2);
val1 <= val2
assert_gt (val1, val2);
expect_gt (val1, val2 );
val1> val2
assert_ge (val1, val2);
expect_ge (val1, val2 );
val1> = val2
string check

Fatal assertion
Nonfatal assertion
Verifies
Assert_streq (expected_str, actual_str );
Expect_streq (expected_str, actual_str );
The two C strings have the same content
Assert_strne (str1, str2 );
Expect_strne (str1, str2 );
The two C strings have different content
Assert_strcaseeq (expected_str, actual_str );
Expect_strcaseeq (expected_str, actual_str );
The two C strings have the same content, ignoring case
Assert_strcasene (str1, str2 );
Expect_strcasene (str1, str2 );
The two C strings have different content, ignoring case
For more information, see
Official documents: http://code.google.com/p/googletest/wiki/GoogleTestPrimer
Recommended documents: http://www.cnblogs.com/coderzh/archive/2009/03/31/1426758.html

Step1. compile the gtest-all.cc and gtest_main.cc files
Step1. compile the gtest-all.cc and gtest_main.cc files

G ++-I $ {gtest_dir}/include-I $ {gtest_dir}-C $ {gtest_dir}/src/gtest-all.cc

G ++-I $ {gtest_dir}/include-I $ {gtest_dir}-C $ {gtest_dir}/src/gtest_main.cc

Step2. package the gtest-all.o and gtest_main.o generated by Step 1 into the static library libgtest.

Ar-RV libgtest. A gtest-all.o gtest_main.o

Step3. compile the code to be tested (assuming the file name is sample. cpp)

G ++-I $ {gtest_dir}/include-C sample. cpp

Step 4. Compile the unit test code (assuming the file name is test. cpp)

G ++-I $ {gtest_dir}/include-C test. cpp

Step 5. Link to libgtest. A or other required libraries to generate executable programs

G ++-I $ {gtest_dir}/include test. O sample. O libgtest. A-o Test

Other libraries, such as the pthread library.

Where, gtest_dir =/usr/src/gtest-1.5.0

The MAKEFILE file is as follows.

Simple version

ALL:

G + +-I/usr/src/gtest-1.5.0/include-I/usr/src/gtest-1.5.0-g-C/usr/src/gtest-1.5.0/src/gtest-all.cc

G + +-I/usr/src/gtest-1.5.0/include-I/usr/src/gtest-1.5.0-g-C/usr/src/gtest-1.5.0/src/gtest_main.cc

Ar-RV libgtest. A gtest-all.o gtest_main.o

G ++-I/usr/src/gtest-1.5.0/include-g-C sample. cpp

G ++-I/usr/src/gtest-1.5.0/include-g-C test. cpp

G ++-I/usr/src/gtest-1.5.0/include-lpthread test. O sample. O libgtest. a-g-o Test

Clean:

Rm test libgtest. A *. o

In fact, the gtest-all.o and gtest_main.o are compressed into libgtest. a library, you can save, directly use the. o file, as shown below.

ALL:

G + +-I/usr/src/gtest-1.5.0/include-I/usr/src/gtest-1.5.0-g-C/usr/src/gtest-1.5.0/src/gtest-all.cc

G + +-I/usr/src/gtest-1.5.0/include-I/usr/src/gtest-1.5.0-g-C/usr/src/gtest-1.5.0/src/gtest_main.cc

G ++-I/usr/src/gtest-1.5.0/include-g-C sample. cpp

G ++-I/usr/src/gtest-1.5.0/include-g-C test. cpp

G ++-I/usr/src/gtest-1.5.0/include-lpthread test. O sample. O gtest-all.o gtest_main.o-g-o Test

Clean:

Rm test *. o

Official version

# Google test directory

Gtest_dir =/usr/src/gtest-1.5.0

# Flags passed to the Preprocessor.

Cppflags + =-I $ (gtest_dir)/include

# Flags passed to the C ++ compiler.

Cxxflags + =-g-wall-wextra

# All Google test headers. Usually you shouldn't change this definition.

Gtest_headers = $ (gtest_dir)/include/gtest/*. h $ (gtest_dir)/include/gtest/Internal/*. h

# All Google test sources

Gtest_srcs _ = $ (gtest_dir)/src/*. CC $ (gtest_dir)/src/*. h $ (gtest_headers)

# All tests produced by this makefile. Remember to add new tests you created to the list.

Tests = test

ALL: $ (tests)

Clean:

Rm-F $ (tests) gtest. A gtest_main.a *. o

Gtest-all.o: $ (gtest_dir)/src/gtest-all.cc # $ (gtest_srcs _)

$ (Cxx) $ (cppflags)-I $ (gtest_dir) $ (cxxflags)-C $ (gtest_dir)/src/gtest-all.cc

Gtest_main.o: $ (gtest_dir)/src/gtest_main.cc # $ (gtest_srcs _)

$ (Cxx) $ (cppflags)-I $ (gtest_dir) $ (cxxflags)-C $ (gtest_dir)/src/gtest_main.cc

Gtest_main.a: gtest-all.o gtest_main.o

$ (AR) $ (arflags) $ @ $ ^

Sample. O: sample. cpp sample. h $ (gtest_headers)

$ (Cxx) $ (cppflags) $ (cxxflags)-C sample. cpp

Test. O: Test. cpp sample. h $ (gtest_headers)

$ (Cxx) $ (cppflags) $ (cxxflags)-C test. cpp

Test: sample. O test. O gtest_main.a

$ (Cxx) $ (cppflags) $ (cxxflags)-lpthread $ ^-o $ @

$ ^ Indicates the dependency, and $ @ indicates the target.

Reference

Readme

Makefile of sample
 

This articleArticleSource: Institute of Development http://edu.codepub.com Source: http://edu.codepub.com/2011/0116/28837.php

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.