Testing fixture (Test fixtures): Use the same data configuration for multiple tests
If you find yourself writing two or more tests to manipulate similar data, you can use a test fixture. It allows you to repeatedly use the same object configuration for several different tests.
To create a fixture, simply:
1. From:: Testing:: Test derives a class. Use protected: or public: Start its body, because we want to access the fixture member from the subclass.
2. In the class, declare any objects that you intend to use.
3. If required, you can write a default constructor or Setup () function to prepare the object for each test. A common mistake is to spell setup () for setup () with a small U--don't let this happen to you.
4. If necessary, write a destructor or teardown () function to free any resources that you have allocated in Setup (). To learn when you should use constructors/destructors, read this FAQ entry when you should use Setup ()/TearDown ().
5. If necessary, define the subroutine for the test to be shared.
When using a fixture, use Test_f () instead of test () because it allows you to access the objects and subroutines in the test fixture:
Test_f (Test_case_name, test_name) {...}?
As with Test (), the first parameter is the test case name, but for Test_f () it must be the name of the test fixture class. You may have guessed it: _f is a fixture.
Unfortunately, the C + + macro system does not allow us to create a macro that can handle two types of tests. Using the wrong macro can cause a compiler error.
In addition, before you use it in Test_f (), you must first define a test fixture class, or you will get the compiler error "virtual outside class declaration".
For each test defined with Test_f (), Google test will:
1. Create a new test fixture at run time
2. Immediately through Setup () initialization,
3. Run the test
4. Clear by calling Teardown ()
5. Remove the test fixture. Note that different tests in the same test case have different test fixture objects, and Google testing always removes the test fixture and then creates the next Test fixture. Google testing does not reuse the same test fixture for multiple tests. one test any change to the fixture does not affect the other tests .
For example, let's write a test for a FIFO queue class named Queue, which has the following interfaces:
Template <typename e>//E is the element type.class queue {public: queue (); void Enqueue (const e& element); e* Dequeue (); Returns NULL If the queue is empty. size_t size () const;
First, define a fixture class. By convention, you should give it the name Footest, where Foo is the class being tested.
Class Queuetest:public:: testing::test {protected: virtual void SetUp () { q1_. Enqueue (1); Q2_. Enqueue (2); Q2_. Enqueue (3); } virtual void TearDown () {} queue<int> q0_; Queue<int> q1_;
In this case, teardown () is not required because we do not have to clean up after each test, except what the destructor has done.
Now we will write the test using Test_f () and this fixture.
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 ());
The above uses Assert_ * and expect_ * assertions. The rule of thumb is to use expect_ * when you want the test to continue to show more errors after the assertion fails, or to continue using Assert_ * After the failure has no meaning. For example, the second assertion in the Dequeue test is assert_true (n! = null), because we need to dereference pointer n later, which causes N to be null when Segfault.
When these tests are run, the following happens:
1.Google test Constructs a Queuetest object (which we call T1).
2.t1. SetUp () initializes the T1.
3. The first Test (isemptyinitially) runs on T1.
4.t1. TearDown () cleans up after the test is complete.
The 5.t1 is reconstructed.
6. The above steps are repeated on another Queuetest object, this time running the Dequeueworks test.
Second, how to use the word fixture to enable multiple test cases to reuse a test fixture
1. When defining a test fixture, you specify the name of the test case that will use this fixture. Therefore, the test fixture can only be used by one test case .
Sometimes, multiple test cases may require the use of the same or slightly different test fixture. For example, you may want to ensure that all tests of the GUI library do not leak important system resources, such as fonts and brushes. In Google testing, you can do
This is done by placing the shared logic in a super (such as "Super class") test fixture, and then having each test case use a fixture derived from this super fixture.
In this example, we want to make sure that each test is completed within 5 seconds. If the test runs for a long time, we think the test failed.
We put the test time code in a test fixture called "QuickTest". QuickTest is designed to be a super fixture derived from other fixtures, so there is no test case named "QuickTest".
We will then export multiple test fixtures from the quicktest.
Class Quicktest:public Testing::test {protected://Remember that SetUp () are run immediately before a Test starts.//this is a good place to record the start time.//this method executes virtual void SetUp () {start_time_ = time (NULL) before each test;} TearDown () is invoked immediately after a test finishes. Here we//check if the test is too slow.//this method executes virtual void TearDown () after each test () {//Gets the time when the test Finishe Sconst time_t end_time = time (NULL);//Asserts that the test took no more than-seconds. Did you//know, can use assertions on SetUp () and TearDown () as//well? Expect_true (end_time-start_time_ <= 5) << "The test took too long.";} The UTC time (in seconds) when the test startstime_t start_time_;};
2. We define a integerfunctiontest inherited QuickTest, and all tests that use the fixture will be automatically requested quickly.
Class Integerfunctiontest:public QuickTest {//We don ' t need any + logic than already in the QuickTest fixture.//the Refore the body is empty.};
3. We can now write tests in the integer Function test test case.
Test_f (Integerfunctiontest, factorial) {//Tests factorial of negative numbers. Expect_eq (1, factorial (-5)); Expect_eq (1, factorial (-1)); EXPECT_GT (factorial ( -10), 0);//Tests factorial of 0.expect_eq (1, factorial (0));//Tests factorial of positive numbers. Expect_eq (1, factorial (1)); Expect_eq (2, factorial (2)); Expect_eq (6, factorial (3)); Expect_eq (40320, factorial (8));}
4. The next test case (named "Queuetest") also needs to be fast, so we derive another fixture from QuickTest.
The Queuetest test fixture has some logical and shared objects, in addition to the quicktest. We define extra things in the body of the test fixture as usual.
Class Queuetest:public QuickTest {protected:virtual void SetUp () {//First, we need to set up the super fixture (Quickte ST). Quicktest::setup ();//Second, some additional SetUp for this fixture.q1_. Enqueue (1); q2_. Enqueue (2); q2_. Enqueue (3);} By default, TearDown () inherits the behavior of//Quicktest::teardown (). As we have no additional cleaning work//for queuetest, we omit it here.////virtual void TearDown () {// Quicktest::te Ardown ();//}queue<int> q0_; Queue<int> q1_; Queue<int> q2_;};
Next, we can write some tests with queuetest.
If necessary, you can obtain further test fixtures from the derived fixture itself. For example, you can derive another fixture from Queuetest. Google testing has no limits on the depth of the hierarchy. In practice, however, you may not want it to be too deep to confuse.
Google C + + unit Test Framework---testfixture use