Google C ++ unit test framework (gtest) series tutorial 3-Test firmware)

Source: Internet
Author: User

Introduction

In the Google C ++ unit testing (gtest) series of tutorials-assertion and function testing, we learned about assertion statements and how to use test () for function testing, in the use of test (), we are exposed to the way in which a test case contains multiple test instances. Multiple test instances may need to perform acquaintance Data configuration and initialization operations. Therefore, gtest provides test fixture to help us manage data.

"Lagging" approach

Before testing the firmware, let's take a look at the following test example:

Template <typename E>//E is the element type.
ClassQueue {
Public:
Queue ();
VoidEnqueue (ConstE & element );
E * dequeue ();//Returns NULL if the queue is empty.
Size_t size ()Const;
...
};

Suppose we want to test the above queue class and write a test based on the usage of test () We learned earlier.CodeAs follows:

 // Test solution 1 
Test (queuetest, isemptyinitially ){
Queue <Int> Q0 _ ;
Expect_eq ( 0 , Q0 _. Size ());
}
Test (queuetest, dequeueworks ){
Queue<Int>Q0 _;
Queue<Int>Q1 _;
Queue<Int>Q2 _;

Q1 _.Enqueue(1);
Q2 _.Enqueue(2);
Q2 _.Enqueue(3);

Int * N = q0 _. dequeue ();
Expect_eq (null, N );

N = Q1 _. dequeue ();
Assert_true (n! = NULL );
Expect_eq ( 1 , * N );
Expect_eq ( 0 , Q1 _. Size ());
Delete N;

N = Q2 _. dequeue ();
Assert_true (n! = NULL );
Expect_eq ( 2 , * N );
Expect_eq ( 1 , Q2 _. Size ());
Delete N;
}

I wonder if you have found the problem? Yes. duplicate code exists in the initialization part of the test data in the red font! This example contains only two test instances. The problem of duplicate code is not prominent, but for dozens or even hundreds of test instances, we need another way to manage our initialization data.

Test Fixture)

The purpose of the firmware test is to manage the data that will be used by two or more test instances. The following describes how to use the firmware test to complete the test:

First, we need to define a firmware class. Generally, the firmware class is named in the footest format. foo is the name of the tested class:

ClassQueuetest:Public: Testing: test {
Protected:
Virtual VoidSetup (){
Q1 _. enqueue (1);
Q2 _. enqueue (2);
Q2 _. enqueue (3);
}
//Virtual void teardown (){}
Queue <Int> Q0 _;
Queue <Int> Q1 _;
Queue <Int> Q2 _;
};

The method for defining the firmware class is:

    1. Write a class inherited from: Test. To enable the subclass of this class to access the data of this class, use public or protected as the access control identifier;
    2. In this class, define the data that will be used by the test instance;
    3. Use the setup () method or default constructor for data initialization, and use the teardown () method or destructor for data cleaning. Note the spelling of setup () and teardown;
    4. If necessary, you can also define member functions in this class. Just like the initialization data, the member functions defined here can be reused by the test instance.

Next, let's look at how to compile the corresponding test instance. First, we need to use a new macro:

 
Test_f (test_case_name, test_name ){
... Test body...
}

Test_f () must be used after the firmware definition is tested. The two parameters have the same meanings as the parameters of test (), but the first parameter of test_f () must be the name of the firmware class.

In combination with the above queuetest to test the firmware, we write the test code as follows:

// Test solution 2
Test_f (queuetest, isemptyinitially ){
Expect_eq (0, Q0 _. Size ());
}

Test_f (queuetest, dequeueworks ){
Int* N = q0 _. dequeue ();
Expect_eq (null, N );

N = Q1 _. dequeue ();
Assert_true (n! = NULL );
Expect_eq (1, * N );
Expect_eq (0, Q1 _. Size ());
Delete N;

N = Q2 _. dequeue ();
Assert_true (n! = NULL );
Expect_eq (2, * N );
Expect_eq (1, Q2 _. Size ());
Delete N;
}

We can see that the usage of test_f () is not much different from that of test (). When the above two test instances run, gtest does the following for us:

    1. Construct a queuetest object (assuming T1 );
    2. Call t1.setup () to initialize the T1 object;
    3. The first test instance (Isemptyinitially) Use T1 for testing;
    4. Call t1.teardown () to clear data;
    5. Destroy object T1;
    6. Create a new queuetest object for the next test instanceDequeueworks repeats the preceding steps.

It can be seen that gtest creates an independent initialization data for each test instance by creating and destroying firmware objects. The above two test schemes have the same purpose and result, however, solution 2 eliminates the repeated code generated by data initialization by using the firmware test.

Firmware class)

C ++ class has the inheritance feature, so that we can flexibly define the firmware class. We can abstract the features of multiple firmware classes to form a base class, to further achieve code reuse and data reuse, let's look at the following example.

 Class Quicktest: Public Testing: test {
Protected :
// This is a good place to record the start time.
Virtual Void Setup (){
Start_time _ = Time (null );
}
// Check if the test was too slow.
Virtual Void Teardown (){
// Gets the time when the test finishes
Const Time_t end_time = Time (null );
// Asserts that the test took no more ~ 5 seconds.
Expect_true (end_time-start_time _ <= 5 ) < " The test took too long. " ;
}

This firmware class makes a simple analysis on the running time of the test instance. It utilizes the features of setup () before the test instance runs, teardown () after the test instance runs, if the test instance lasts for more than 5 seconds, the test instance fails to be detected. You can also use asserted statements in the setup () and teardown () functions.

Suppose we have execution time limits on the test instances of the queue class, we can write the firmware class inherited from quicktest:

ClassQueuetest:PublicQuicktest {
//......
};

According to this definition, the execution time of the test instance associated with queuetest is detected.

Summary

This article describes the causes and methods for using gtest to test the firmware. At last, we propose that you can flexibly define the firmware for testing through class inheritance. The next section describes how to use gtest value parameterization and type parameterization.

Reference: googletest Project

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.