Fork me on GitHub

Gtest:事件

前言

有时候在测试的时候,我们会在测试前做一些初始化活动,和测试后做一些清理工作,gtest提供了多种事件机制,非常方便我们在案例之前或之后做一些操作。总结一下gtest的事件一共有3种:

  1. 全局的,所有案例执行前后。
  2. TestSuite级别的,在某一批案例中第一个案例前,最后一个案例执行后。
  3. TestCase级别的,每个TestCase前后。

接下来按照倒叙3→2→1介绍如何使用事件机制

TestCase事件 

TestCase事件是挂在每个案例执行前后的,实现方式和上面的几乎一样,不过需要实现的是SetUp方法和TearDown方法:

1. SetUp()方法在每个TestCase之前执行

2. TearDown()方法在每个TestCase之后执行

演示代码(Linux环境)

main.cpp

#include "sample-inl.h"
#include "gtest/gtest.h"
namespace {
    class QueueTestSmpl : public testing::Test {
    protected:

        virtual void SetUp() {
            //q0_.Enqueue(1);
            q1_.Enqueue(1);
            q1_.Enqueue(2);
            q2_.Enqueue(3);
        }

        virtual void TearDown() {
        }

        static int Double(int n) {
            return 2 * n;
        }

        // A helper function for testing Queue::Map().
        void MapTester(const Queue<int> * q) {
            // Creates a new queue, where each element is twice as big as the
            // corresponding one in q.
            const Queue<int> * const new_q = q->Map(Double);

            // Verifies that the new queue has the same size as q.
            ASSERT_EQ(q->Size(), new_q->Size());

            // Verifies the relationship between the elements of the two queues.
            for (const QueueNode<int>*n1 = q->Head(), *n2 = new_q->Head();
                n1 != nullptr; n1 = n1->next(), n2 = n2->next()) {
                EXPECT_EQ(2 * n1->element(), n2->element());
            }

            delete new_q;
        }

        // Declares the variables your tests want to use.
        Queue<int> q0_;
        Queue<int> q1_;
        Queue<int> q2_;
    };

    // Tests Dequeue().
    TEST_F(QueueTestSmpl, Dequeue) {
        int * n = q0_.Dequeue();
        EXPECT_TRUE(n == nullptr);

        n = q1_.Dequeue();
        ASSERT_TRUE(n != nullptr);
        EXPECT_EQ(1, *n);
        EXPECT_EQ(1u, q1_.Size());
        delete n;

        n = q1_.Dequeue();
        ASSERT_TRUE(n != nullptr);
        EXPECT_EQ(2, *n);
        EXPECT_EQ(0u, q1_.Size());
        delete n;

        n = q2_.Dequeue();
        ASSERT_TRUE(n != nullptr);
        EXPECT_EQ(3, *n);
        EXPECT_EQ(0u, q2_.Size());
        delete n;
    }
}  // namespace
View Code

sample-inl.h

#ifndef GTEST_SAMPLES_SAMPLE_INL_H_
#define GTEST_SAMPLES_SAMPLE_INL_H_

#include <stddef.h>

template <typename E>  // E is the element type
class Queue;

template <typename E>  // E is the element type
class QueueNode {
    friend class Queue<E>;

public:
    // Gets the element in this node.
    const E& element() const { return element_; }

    // Gets the next node in the queue.
    QueueNode* next() { return next_; }
    const QueueNode* next() const { return next_; }

private:
    // Creates a node with a given element value.  The next pointer is
    // set to NULL.
    explicit QueueNode(const E& an_element)
        : element_(an_element), next_(nullptr) {}

    // We disable the default assignment operator and copy c'tor.
    const QueueNode& operator = (const QueueNode&);
    QueueNode(const QueueNode&);

    E element_;
    QueueNode* next_;
};

template <typename E>  // E is the element type.
class Queue {
public:
    // Creates an empty queue.
    Queue() : head_(nullptr), last_(nullptr), size_(0) {}

    // D'tor.  Clears the queue.
    ~Queue() { Clear(); }

    // Clears the queue.
    void Clear() {
        if (size_ > 0) {
            // 1. Deletes every node.
            QueueNode<E>* node = head_;
            QueueNode<E>* next = node->next();
            for (; ;) {
                delete node;
                node = next;
                if (node == nullptr) break;
                next = node->next();
            }

            // 2. Resets the member variables.
            head_ = last_ = nullptr;
            size_ = 0;
        }
    }

    size_t Size() const { return size_; }

    QueueNode<E>* Head() { return head_; }
    const QueueNode<E>* Head() const { return head_; }

    QueueNode<E>* Last() { return last_; }
    const QueueNode<E>* Last() const { return last_; }

    void Enqueue(const E& element) {
        QueueNode<E>* new_node = new QueueNode<E>(element);

        if (size_ == 0) {
            head_ = last_ = new_node;
            size_ = 1;
        }
        else {
            last_->next_ = new_node;
            last_ = new_node;
            size_++;
        }
    }

    E* Dequeue() {
        if (size_ == 0) {
            return nullptr;
        }

        const QueueNode<E>* const old_head = head_;
        head_ = head_->next_;
        size_--;
        if (size_ == 0) {
            last_ = nullptr;
        }

        E* element = new E(old_head->element());
        delete old_head;

        return element;
    }

    template <typename F>
    Queue* Map(F function) const {
        Queue* new_queue = new Queue();
        for (const QueueNode<E>* node = head_; node != nullptr;
            node = node->next_) {
            new_queue->Enqueue(function(node->element()));
        }

        return new_queue;
    }

private:
    QueueNode<E>* head_;  // The first node of the queue.
    QueueNode<E>* last_;  // The last node of the queue.
    size_t size_;  // The number of elements in the queue.

    // We disallow copying a queue.
    Queue(const Queue&);
    const Queue& operator = (const Queue&);
};

#endif  // GTEST_SAMPLES_SAMPLE3_INL_H_
View Code

 

TestSuite事件

这个相对来说比较简单,相对上面的实现就是替换成静态的SetUpTestCase,代码

class FooTest : public testing::Test {
 protected:
 //准备资源
  static void SetUpTestCase() {
    shared_resource_ = new ;
  }
  //释放资源
  static void TearDownTestCase() {
    delete shared_resource_;
    shared_resource_ = NULL;
  }
  // 资源
  static T* shared_resource_;
};

  

全局事件

也是很简单的,就是继承于testing::Environment而已。

class FooEnvironment: public testing::Environment
{
    public:
        virtual void SetUp()
        {
            printf("Environment SetUp!\n");
            a = 100;
        }
        virtual void TearDown()
        {
            printf("Environment TearDown!\n");
        }
        int a;     //共享数据
};
FooEnvironment* foo_env;  //对象指针声明
TEST(firstTest, first)    //访问共享数据并改变它的值
{
    printf("in the firstTest, foo_env->p is %d\n", foo_env->a);
    foo_env->a ++;
}
TEST(secondTest, second)  //访问共享数据
{
    printf("in the secondTest, foo_env->p is %d\n", foo_env->a);
}
int main(int argc, char* argv[])
{
    foo_env = new FooEnvironment;
    testing::AddGlobalTestEnvironment(foo_env);     //注册
    testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
}

  

posted @ 2019-01-06 19:14  克拉默与矩阵  阅读(513)  评论(0编辑  收藏  举报