一、测试夹具(Test Fixtures):对多个测试使用相同的数据配置

如果你发现自己写了两个或更多的测试来操作类似的数据,你可以使用测试夹具。它允许您为几个不同的测试重复使用相同的对象配置。

要创建夹具,只需:

1.从:: testing :: Test派生一个类。 使用protected:或public:开始它的主体,因为我们想从子类     访问fixture成员。
  2.在类中,声明你打算使用的任何对象。
  3.如果需要,可以编写默认构造函数或SetUp()函数来为每个测试准备对象。 一个常见的错误是     拼写SetUp()为Setup()与一个小u -- 不要让这种情况发生在你身上。
  4.如果需要,写一个析构函数或TearDown()函数来释放你在SetUp()中分配的任何资源。 要     学习什么时候应该使用构造函数/析构函数,当你应该使用SetUp()/ TearDown()时,请阅读这个 FAQ entry.。
  5.如果需要,定义要分享的测试的子程序。

当使用夹具时,使用TEST_F()而不是TEST(),因为它允许您访问测试夹具中的对象和子程序:

TEST_F(test_case_name, test_name) {
... test body ...
}​

和TEST()一样,第一个参数是测试用例名,但是对于TEST_F()必须是测试夹具类的名称。 你可能猜到了:_F是夹具。

不幸的是,C ++宏系统不允许我们创建一个可以处理两种类型的测试的宏。 使用错误的宏会导致编译器错误。

另外,在TEST_F()中使用它之前,你必须首先定义一个测试夹具类,否则将得到编译器错误“virtual outside class declaration”。

对于使用TEST_F()定义的每个测试,Google Test将:

1.在运行时创建一个新的测试夹具
  2.立即通过SetUp()初始化,
  3.运行测试
  4.通过调用TearDown()清除
  5.删除测试夹具。 请注意,同一测试用例中的不同测试具有不同的测试夹具对象,Google测试始     终会删除测试夹具,然后再创建下一个测试夹具。 Google测试不会为多个测试重复使用相同的       测试夹具。一个测试对夹具的任何更改不会影响其他测试

例如,让我们为名为Queue的FIFO队列类编写测试,它有以下接口:

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;
...
};

 首先定义一个夹具类。按照惯例,你应该给它名称FooTest,其中Foo是被测试的类。 

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_;
Queue<int> q2_;
};

在这种情况下,不需要TearDown(),因为我们不必在每次测试后清理,除了析构函数已经做了什么。

现在我们将使用TEST_F()和这个夹具编写测试。

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;
}

上面使用ASSERT_ *和EXPECT_ *断言。 经验法则( The rule of thumb )是当你希望测试在断言失败后继续显示更多错误时使用EXPECT_ *,或是在失败后继续使用ASSERT_ *没有意义。 例如,Dequeue测试中的第二个断言是ASSERT_TRUE(n!= NULL),因为我们需要稍后解引用指针n,这将导致n为NULL时的segfault。

当这些测试运行时,会发生以下情况:

1.Google Test构造了一个QueueTest对象(我们称之为t1)。 
  2.t1.SetUp()初始化t1。 
  3.第一个测试(IsEmptyInitially)在t1上运行。 
  4.t1.TearDown()在测试完成后清理。 
  5.t1被析构。 
  6.以上步骤在另一个QueueTest对象上重复,这次运行DequeueWorks测试。

二、如何通过字夹具使多个测试用例重用一个测试夹具

1. 当定义测试夹具时,您指定将使用此夹具的测试用例的名称。 因此,测试夹具只能由一个测试用例使用
   有时,多个测试用例可能需要使用相同或稍微不同的测试夹具。 例如,您可能需要确保GUI库的所有测试不会泄漏重要的系统资源,如字体和画笔。 在Google测试中,您可以做到
  这通过将共享逻辑放在超级(如“超级类”)测试夹具中,然后让每个测试用例使用从这个超级夹具派生的夹具。
   在这个示例中,我们希望确保每个测试在〜5秒内完成。 如果测试运行时间较长,我们认为测试失败。

我们把测试时间的代码放在一个叫做“QuickTest”的测试夹具中。 QuickTest旨在作为其他夹具派生的超级夹具,因此没有名为“QuickTest”的测试用例。

然后,我们将从QuickTest中导出多个测试夹具。

class QuickTest : public testing::Test {
protected:
// Remember that SetUp() is run immediately before a test starts.
// This is a good place to record the start time.
//这个方法在每一个test之前执行
virtual void SetUp() {
start_time_ = time(NULL);
}
// TearDown() is invoked immediately after a test finishes. Here we
// check if the test was too slow.
//这个方法在每一个test之后执行
virtual void TearDown() {
// Gets the time when the test finishes
const time_t end_time = time(NULL);
// Asserts that the test took no more than ~5 seconds. Did you
// know that you can use assertions in 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 starts
time_t start_time_;
};

2.我们定义一个IntegerFunctionTest继承QuickTest, 使用该夹具的所有测试将自动要求快速。

class IntegerFunctionTest : public QuickTest {
// We don't need any more logic than already in the QuickTest fixture.
// Therefore the body is empty.
};

3.现在我们可以在Integer Function Test测试用例中写测试了。

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. 下一个测试用例(名为“QueueTest”)也需要很快,所以我们从QuickTest派生另一个夹具。
QueueTest测试夹具有一些逻辑和共享对象,除了QuickTest中已有的。 我们像往常一样在测试夹具的主体内定义额外的东西。

class QueueTest : public QuickTest {
protected:
virtual void SetUp() {
// First, we need to set up the super fixture (QuickTest).
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::TearDown();
// } Queue<int> q0_;
Queue<int> q1_;
Queue<int> q2_;
};

  接下来我们就可以用QueueTest写一些测试。

// Tests the default constructor.
TEST_F(QueueTest, DefaultConstructor) {
EXPECT_EQ(0u, q0_.Size());
}

  如有必要,您可以从派生的夹具本身获得进一步的测试夹具。 例如,您可以从QueueTest派生另一个夹具。 Google测试对层次结构的深度没有限制。 然而,在实践中,你可能不希望它太深以至于混淆。

Google C++单元测试框架GoogleTest---TestFixture使用的更多相关文章

  1. Google C++单元测试框架GoogleTest(总)

    之前一个月都在学习googletest框架,对googletest的文档都翻译了一遍,也都发在了之前的博客里,另外其实还有一部分的文档我没有发,就是GMock的CookBook部分:https://g ...

  2. Google C++单元测试框架GoogleTest---GMock的CheatSheet文档

    CheatSheet文档中包含了GMock所有常用的东西,看了这个基本上就可以用它了,本文接上篇博文:Google C++单元测试框架GoogleTest---Google Mock简介--概念及基础 ...

  3. Google C++单元测试框架GoogleTest---AdvancedGuide(译文)下

    因为AdvancedGuide文档太长,分上下两部分,本文档接googletest--AdvancedGuide(译文)上:Google C++单元测试框架GoogleTest---AdvancedG ...

  4. Google C++单元测试框架GoogleTest---GTest的Sample1和编写单元测试的步骤

    如果你还没有搭建gtest框架,可以参考我之前的博客:http://www.cnblogs.com/jycboy/p/6001153.html.. 1.The first sample: sample ...

  5. Google C++单元测试框架

    一.概述 Google C++单元测试框架(简称Gtest),可在多个平台上使用(包括Linux, Mac OS X, Windows, Cygwin和Symbian),它提供了丰富的断言.致命和非致 ...

  6. Google C++单元测试框架GoogleTest---Google Mock简介--概念及基础语法

    就在昨天终于做了gtest的分享,我的预研工作终于结束了,感觉离我辞职的日子不远了,毕竟是专注java二百年啊,要告别实习啦.. 这篇是GoogleMock的简介文档,会在后边附带一个自己的例子. 一 ...

  7. Google C++单元测试框架---Gtest框架简介(译文)

    一.设置一个新的测试项目 在用google test写测试项目之前,需要先编译gtest到library库并将测试与其链接.我们为一些流行的构建系统提供了构建文件: msvc/ for Visual ...

  8. c++单元测试框架googletest

    一.概述 Googletest是一个用来写C++单元测试的框架,它是跨平台的,可应用在windows.linux.Mac等OS平台上: 代码框架: [root@docker googletest-re ...

  9. Google C++单元测试框架GoogleTest---值参数化测试

    值参数化测试允许您使用不同的参数测试代码,而无需编写同一测试的多个副本. 假设您为代码编写测试,然后意识到您的代码受到布尔参数的影响. TEST(MyCodeTest, TestFoo) { // A ...

随机推荐

  1. 【开源】OSharp框架解说系列(5.1):EntityFramework数据层设计

    OSharp是什么? OSharp是个快速开发框架,但不是一个大而全的包罗万象的框架,严格的说,OSharp中什么都没有实现.与其他大而全的框架最大的不同点,就是OSharp只做抽象封装,不做实现.依 ...

  2. Hawk: 20分钟无编程抓取大众点评17万数据

    1. 主角出场:Hawk介绍 Hawk是沙漠之鹰开发的一款数据抓取和清洗工具,目前已经在Github开源.详细介绍可参考:http://www.cnblogs.com/buptzym/p/545419 ...

  3. hdu4831 Scenic Popularity(线段树)

    题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=4831 题目大概意思就是有多个风景区和休息区,每个风景区有热度,休息区的热度与最接近的分景区的热度相同, ...

  4. 小菜学习Winform(五)窗体间传递数据

    前言 做项目的时候,winfrom因为没有B/S的缓存机制,窗体间传递数据没有B/S页面传递数据那么方便,今天我们就说下winfrom中窗体传值的几种方式. 共有字段传递 共有字段传递实现起来很方便, ...

  5. 关于在用curl函数post网页数据时,遇上表单提交 type为submit 类型而且没有name和id时可能遇到的问题及其解决方法

    curl函数库实现爬网页内容的链接在 http://www.cnblogs.com/linguanh/p/4292316.html 下面这个是没有name和id 标识的 <input type= ...

  6. 用CSS3动画,让页面动起来

    以前就听说过有个库,叫animate.css,但是自己并没有在实际项目中使用过,这次正好要做个招聘页面,得以利用一下这个库,在经常会卡顿的UC浏览器中也能流畅执行. 扫描下面的二维码,可以看到在线的d ...

  7. PowerPoint基础

    一.基础 默认后缀ppt,pptx office2003和以后的版本只支持ppt, 可以将pptx另存为ppt97-2003 二.修改PPT尺寸 三.新建幻灯片 四.字体与段落设置 五.主题与字体 六 ...

  8. 一次发现underscore源码bug的经历以及对学术界『拿来主义』的思考

    事情是如何发生的 最近干了件事情,发现了 underscore 源码的一个 bug.这件事本身并没有什么可说的,但是过程值得我们深思,记录如下,各位看官仁者见仁智者见智. 平时有浏览园区首页文章的习惯 ...

  9. 有了jsRender,妈妈再也不用担心我用jq拼接DOM拼接的一团糟了、页面整齐了、其他伙伴读代码也不那么费劲了

    写在前面 说来也很巧, 下午再做一个页面,再普通不过的分页列表,我还是像往常一样,基于MVC环境下,我正常用PagedList.MVC AJAX做无刷新分页,这时候问题就来了,列表数据中有个轮播图用到 ...

  10. [AngularJS] AngularJS系列(7) 进阶篇之promise

    目录 使用promise 补充说明 $q.all $q.when 在上节中,我们在http中使用了then 和 在ngResource中返回了一个'延迟对象'. 本节介绍一下angular中的prom ...