当前位置: 首页 > 编程日记 > 正文

gtest简介及简单使用

gtest是一个跨平台(Liunx、Mac OS X、Windows、Cygwin、Windows CE and Symbian)的C++测试框架,有google公司发布。gtest测试框架是在不同平台上为编写C++测试而生成的。

从http://code.google.com/p/googletest/downloads/detail?name=gtest-1.7.0.zip&can=2&q=下载最新的gtest-1.7.0版本

在Windows下编译gtest步骤:(1)、将gtest-1.7.0.zip进行解压缩;(2)、用vs2010打开msvc目录下的gtest.sln工程,需要进行转换,生成gtest、gtest_main、gtest_prod_test、gtest_unittest四个工程;(3)、分别在Debug和Release下,选中Solution ‘gtest’,点击右键,执行Rebuild Solution,会在msvc/gtest/Debug下生成gtestd.lib、gtest_maind.lib库,在msvc/gtest/Release下生成gtest.lib、gtest_main.lib库。

Widows下举例:(1)、在Solution  ‘gtest’中新建一个Testgtest工程;(2)、新加一个fun.h文件,此文件内容为:

#ifndef _FOO_H_
#define _FOO_H_int add(int a, int b)
{return a + b;
}#endif//_FOO_H_

(3)、修改工程属性:A、General -> Character Set: Use Multi-Byte Character Set;B、C/C++ -> General -> Additional IncludeDirectories: ../../gtest-1.7.0/include;C、C/C++ -> Code Generation -> Runtime Library: Debug下, Multi-threaded Debug(/MTd) , Release下,Multi-threaded(MT);

(4)、stdafx.h文件内容为:

#pragma once#include "targetver.h"#include <stdio.h>#include "gtest/gtest.h"

(5)、stdafx.cpp文件内容为:

#include "stdafx.h"#ifdef _DEBUG#pragma comment(lib, "../../gtest-1.7.0/msvc/gtest/Debug/gtestd.lib")#pragma comment(lib, "../../gtest-1.7.0/msvc/gtest/Debug/gtest_maind.lib")
#else#pragma comment(lib, "../../gtest-1.7.0/msvc/gtest/Release/gtest.lib")#pragma comment(lib, "../../gtest-1.7.0/msvc/gtest/Release/gtest_main.lib") 
#endif

(6)、Testgtest.cpp文件内容为:

#include "stdafx.h"
#include "fun.h"TEST(fun, add)
{EXPECT_EQ(1, add(2,-1));EXPECT_EQ(5, add(2,3));
}int main(int argc, char* argv[])
{::testing::InitGoogleTest(&argc, argv);return RUN_ALL_TESTS();
}

运行此工程即可输出相关信息。修改EXPECT_EQ可查看结果值为错误时的输出信息。


在Ubuntu下编译gtest步骤:在gtest-1.7.0.zip目录下,依次执行:unzip gtest-1.7.0.zip ;

cd  gtest-1.7.0 ; ./configure ;  make  ; cd  lib ; mv .libs libs ;此时,会在gtest-1.7.0/lib/libs目录下生成libgtest.a和libgtest_main.a库(说明:gtest-1.7.0/lib下会生成libgtest.la和libgtest_main.la库,.la为libtool生成的共享库,其实是个配置文档。lib下的libs文件刚开始生成时是隐藏文件,需要用mv指令转成正常文件,libs除了libgtest.a和libgtest_main.a库还有其它一些文件,没有什么用,全部删除即可)。

Ubuntu下举例:(1)、在gtest-1.7.0同一目录下新建一个test文件;(2)、此test文件夹下存放fun.h和gtest_test.cpp文件,fun.h文件内容与Windows下的fun.h内容完全一致;

(3)、gtest_test.cpp文件内容为:

#include "../gtest-1.7.0/include/gtest/gtest.h"#include "fun.h"TEST(fun, add){EXPECT_EQ(1, add(2,-1));EXPECT_EQ(5, add(2,3));}int main(int argc, char** argv){::testing::InitGoogleTest(&argc, argv);return RUN_ALL_TESTS();}

(4)、将终端定位到/test目录下,输入  g++  -g  gtest_test.cpp -o  gtest_test  -I../gtest-1.7.0/include  -L../gtest-1.7.0/lib/libs  -lgtest  -lgtest_main  -lpthread ;会在/test目录下生成gtest_test执行文件;

(5)、执行 ./gtest_test 输出信息与Windows下一致。


更通用的做法是:不必在每个平台下分别编译生成静态库,可以直接使用/fused-src/gtest下的gtest.h和gtest-all.cc两个文件,此两个文件包含了所有你需要用到的Google Test的东西。如果没有/fuse-src这个文件,可以使用/scripts/fuse_gtest_files.py这个文件生成,操作步骤是:(1)、配置好python;(2)、打开命令提示符,将其定位到/scripts文件夹下,输入命令:python  fuse_gtest_files.py fused_gtest ;会在/scripts文件夹下生成一个fused_gtest/gtest文件,里面包含gtest.h和gtest-all.cc两个文件,此两个文件和/fuse-src中的同名文件内容是完全一致的。


下面是对gtest的一些总结:

1.  TEST(test_case_name, test_name)

TEST_F(test_fixture,test_name)

TEST宏的作用是创建一个简单测试,它定义了一个测试函数,在这个函数里可以使用任何C++代码并使用提供的断言来进行检查。

多个测试场景需要相同数据配置的情况,用TEST_F。

2.  gtest中,断言的宏可以分为两类,一类是ASSERT系列,一类是EXPECT系列。

{ASSERT|EXPECT}_EQ(expected,actual): Tests that expected == actual

{ASSERT|EXPECT}_NE(v1,v2):           Tests that v1 != v2

{ASSERT|EXPECT}_LT(v1,v2):           Tests that v1 < v2

{ASSERT|EXPECT}_LE(v1,v2):           Tests that v1 <= v2

{ASSERT|EXPECT}_GT(v1,v2):           Tests that v1 > v2

{ASSERT|EXPECT}_GE(v1,v2):           Tests that v1 >= v2

EXPECT_*和ASSERT_*的区别:(1)、EXPECT_*失败时,案例继续往下执行;(2)、ASSERT_*失败时,直接在当前函数中返回,当前函数中ASSERT_*后面的语句将不会执行,退出当前函数,并非退出当前案例。

断言:布尔值检查、数值型数据检查、字符串检查、显示成功或失败、异常检查、Predicate Assertions、浮点型检查、Windows HRESULT assertions、类型检查。

3.  ::testing::InitGoogleTest(&argc,argv):gtest的测试案例允许接收一系列的命令行参数,将命令行参数传递给gtest,进行一些初始化操作。gtest的命令行参数非常丰富。

4.  RUN_ALL_TESTS():运行所有测试案例。

5.  可以通过操作符"<<"将一些自定义的信息输出,如在EXPECT_EQ(v1, v2)<< "thisis a error! "

6.  gtest的事件一共有3种:(1)、全局的,所有案例执行前后;(2)、TestSuite级别的,在某一批案例中第一个案例前,最后一个案例执行后;(3)、TestCase级别的,每个TestCase前后。

全局事件:要实现全局事件,必须写一个类,继承testing::Environment类,实现里面的SetUp和TearDown方法。SetUp方法在所有案例执行前执行;TearDown方法在所有案例执行后执行。

TestSuite事件:需要写一个类,继承testing::Test,然后实现两个静态方法:(1)、SetUpTestCase方法在第一个TestCase之前执行;(2)、TearDownTestCase方法在最后一个TestCase之后执行。

TestCase事件:是挂在每个案例执行前后的,需要实现的是SetUp方法和TearDown方法。(1)、SetUp方法在每个TestCase之前执行;(2)、TearDown方法在每个TestCase之后执行。

每个基于gtest的测试过程,是可以分为多个TestSuite级别,而每个TestSuite级别又可以分为多个TestCase级别。这样分层的结构的好处,是可以针对不同的TestSuite级别或者TestCase级别设置不同的参数、事件机制等,并且可以与实际测试的各个模块层级相互对应,便于管理。

7.  参数化:必须添加一个类,继承testing::TestWithParam<T>,其中T就是你需要参数化的参数类型。

8.  编写死亡测试案例时,TEST的第一个参数,即test_case_name,请使用DeathTest后缀,原因是gtest会优先运行死亡测试案例,应该是为线程安全考虑。

9.  testing::AddGlobalTestEnvironment(newFooEnvironment):在main函数中创建和注册全局环境对象。

10.  对于运行参数,gtest提供了三种设置的途径:(1)、系统环境变量;(2)、命令行参数;(3)、代码中指定FLAG。

命令行参数:(1)、--gtest_list_tests:使用这个参数时,将不会执行里面的测试案例,而是输出一个案例的列表;(2)、 --gtest_filter:对执行的测试案例进行过滤,支持通配符;(3)、--gtest_also_run_disabled_tests:执行案例时,同时也执行被置为无效的测试案例;(4)、--gtest_repeat=[COUNT]:设置案例重复运行次数;(5)、--gtest_color=(yes|no|auto):输出命令行时是否使用一些五颜六色的颜色,默认是auto;(6)、--gtest_print_time:输出命令时是否打印每个测试案例的执行时间,默认是不打印的;(7)、--gtest_output=xml[:DIRECTORY_PATH\|:FILE_PATH:将测试结果输出到一个xml中,如—gtest_output=xml:d:\foo.xml 指定输出到d:\foo.xml ,如果不是指定了特定的文件路径,gtest每次输出的报告不会覆盖,而会以数字后缀的方式创建;(8)、--gtest_break_on_failure:调试模式下,当案例失败时停止,方便调试;(9)、--gtest_throw_on_failure:当案例失败时以C++异常的方式抛出;(10)、--gtest_catch_exceptions:是否捕捉异常,gtest默认是不捕捉异常的,这个参数只在Windows下有效。


在gtest-1.7.0/samples的文件夹中有10个gtest的例子,我将其添加到一个工程中,便于查看:

1. 新建一个gtestSamples的工程;

2. 此工程下的文件包括:(1)、gtest/gtest.h;(2)、gtest-all.cc;(3)、fun.h;(4)、fun.cpp;(5)、gtestSamlpes.cpp。

3. gtest.h和gtest-all.cc两个文件为gtest-1.7.0/fused-src中的原始文件;

4. fun.h文件内容为:

#ifndef _FUN_H_
#define _FUN_H_#include <string.h>
#include <algorithm>// Returns n! (the factorial of n).  For negative n, n! is defined to be 1.
int Factorial(int n);// Returns true if n is a prime number.
bool IsPrime(int n);// A simple string class.
class MyString {
private:const char* c_string_;const MyString& operator=(const MyString& rhs);public:// Clones a 0-terminated C string, allocating memory using new.static const char* CloneCString(const char* a_c_string);//// C'tors// The default c'tor constructs a NULL string.MyString() : c_string_(NULL) {}// Constructs a MyString by cloning a 0-terminated C string.explicit MyString(const char* a_c_string) : c_string_(NULL) {Set(a_c_string);}// Copy c'torMyString(const MyString& string) : c_string_(NULL) {Set(string.c_string_);}//// D'tor.  MyString is intended to be a final class, so the d'tor// doesn't need to be virtual.~MyString() { delete[] c_string_; }// Gets the 0-terminated C string this MyString object represents.const char* c_string() const { return c_string_; }size_t Length() const {return c_string_ == NULL ? 0 : strlen(c_string_);}// Sets the 0-terminated C string this MyString object represents.void Set(const char* c_string);
};// Queue is a simple queue implemented as a singled-linked list.
//
// The element type must support copy constructor.
template <typename E>  // E is the element type
class Queue;// QueueNode is a node in a Queue, which consists of an element of
// type E and a pointer to the next node.
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_(NULL) {}// 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_(NULL), last_(NULL), 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 == NULL) break;next = node->next();}// 2. Resets the member variables.head_ = last_ = NULL;size_ = 0;}}// Gets the number of elements.size_t Size() const { return size_; }// Gets the first element of the queue, or NULL if the queue is empty.QueueNode<E>* Head() { return head_; }const QueueNode<E>* Head() const { return head_; }// Gets the last element of the queue, or NULL if the queue is empty.QueueNode<E>* Last() { return last_; }const QueueNode<E>* Last() const { return last_; }// Adds an element to the end of the queue.  A copy of the element is// created using the copy constructor, and then stored in the queue.// Changes made to the element in the queue doesn't affect the source// object, and vice versa.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_++;}}// Removes the head of the queue and returns it.  Returns NULL if// the queue is empty.E* Dequeue() {if (size_ == 0) {return NULL;}const QueueNode<E>* const old_head = head_;head_ = head_->next_;size_--;if (size_ == 0) {last_ = NULL;}E* element = new E(old_head->element());delete old_head;return element;}// Applies a function/functor on each element of the queue, and// returns the result in a new queue.  The original queue is not// affected.template <typename F>Queue* Map(F function) const {Queue* new_queue = new Queue();for (const QueueNode<E>* node = head_; node != NULL; 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&);
};// A simple monotonic counter.
class Counter {
private:int counter_;public:// Creates a counter that starts at 0.Counter() : counter_(0) {}// Returns the current counter value, and increments it.int Increment();// Prints the current counter value to STDOUT.void Print() const;
};// The prime table interface.
class PrimeTable {
public:virtual ~PrimeTable() {}// Returns true iff n is a prime number.virtual bool IsPrime(int n) const = 0;// Returns the smallest prime number greater than p; or returns -1// if the next prime is beyond the capacity of the table.virtual int GetNextPrime(int p) const = 0;
};// Implementation #1 calculates the primes on-the-fly.
class OnTheFlyPrimeTable : public PrimeTable {
public:virtual bool IsPrime(int n) const {if (n <= 1) return false;for (int i = 2; i*i <= n; i++) {// n is divisible by an integer other than 1 and itself.if ((n % i) == 0) return false;}return true;}virtual int GetNextPrime(int p) const {for (int n = p + 1; n > 0; n++) {if (IsPrime(n)) return n;}return -1;}
};// Implementation #2 pre-calculates the primes and stores the result
// in an array.
class PreCalculatedPrimeTable : public PrimeTable {
public:// 'max' specifies the maximum number the prime table holds.explicit PreCalculatedPrimeTable(int max): is_prime_size_(max + 1), is_prime_(new bool[max + 1]) {CalculatePrimesUpTo(max);}virtual ~PreCalculatedPrimeTable() { delete[] is_prime_; }virtual bool IsPrime(int n) const {return 0 <= n && n < is_prime_size_ && is_prime_[n];}virtual int GetNextPrime(int p) const {for (int n = p + 1; n < is_prime_size_; n++) {if (is_prime_[n]) return n;}return -1;}private:void CalculatePrimesUpTo(int max) {::std::fill(is_prime_, is_prime_ + is_prime_size_, true);is_prime_[0] = is_prime_[1] = false;for (int i = 2; i <= max; i++) {if (!is_prime_[i]) continue;// Marks all multiples of i (except i itself) as non-prime.for (int j = 2*i; j <= max; j += i) {is_prime_[j] = false;}}}const int is_prime_size_;bool* const is_prime_;// Disables compiler warning "assignment operator could not be generated."void operator=(const PreCalculatedPrimeTable& rhs);
};#endif//_FUN_H_

fun.cpp文件内容为:

#include "fun.h"
#include <stdio.h>// Returns n! (the factorial of n).  For negative n, n! is defined to be 1.
int Factorial(int n) {int result = 1;for (int i = 1; i <= n; i++) {result *= i;}return result;
}// Returns true if n is a prime number.
bool IsPrime(int n) {// Trivial case 1: small numbersif (n <= 1) return false;// Trivial case 2: even numbersif (n % 2 == 0) return n == 2;// Now, we have that n is odd and n >= 3.// Try to divide n by every odd number i, starting from 3for (int i = 3; ; i += 2) {// We only have to try i up to the squre root of nif (i > n/i) break;// Now, we have i <= n/i < n.// If n is divisible by i, n is not prime.if (n % i == 0) return false;}// n has no integer factor in the range (1, n), and thus is prime.return true;
}// Clones a 0-terminated C string, allocating memory using new.
const char* MyString::CloneCString(const char* a_c_string) {if (a_c_string == NULL) return NULL;const size_t len = strlen(a_c_string);char* const clone = new char[ len + 1 ];memcpy(clone, a_c_string, len + 1);return clone;
}// Sets the 0-terminated C string this MyString object
// represents.
void MyString::Set(const char* a_c_string) {// Makes sure this works when c_string == c_string_const char* const temp = MyString::CloneCString(a_c_string);delete[] c_string_;c_string_ = temp;
}// Returns the current counter value, and increments it.
int Counter::Increment() {return counter_++;
}// Prints the current counter value to STDOUT.
void Counter::Print() const {printf("%d", counter_);
}

gtestSamlpes.cpp文件的内容为:

#include "gtest/gtest.h"
#include "fun.h"#define BRANCH_1 //BRANCH_1 //BRANCH_2 //BRANCH_3#if defined  BRANCH_1/*-------------------------------------------TEST macro-----------------------*/
//Sample 1: This sample shows how to write a simple unit test for a function,
// using Google C++ testing framework.
//
// Writing a unit test using Google C++ testing framework is easy as 1-2-3:
// Step 1. Include necessary header files such that the stuff your
// test logic needs is declared.
// Step 2. Use the TEST macro to define your tests.
// Step 3. Call RUN_ALL_TESTS() in main().// TEST has two parameters: the test case name and the test name.
// After using the macro, you should define your test logic between a
// pair of braces.  You can use a bunch of macros to indicate the
// success or failure of a test.
// The test case name and the test name should both be valid C++
// identifiers.  And you should not use underscore (_) in the names.// Tests Factorial().
// Tests factorial of negative numbers.
TEST(FactorialTest, Negative) {// This test is named "Negative", and belongs to the "FactorialTest"// test case.EXPECT_EQ(1, Factorial(-5));EXPECT_EQ(1, Factorial(-1));EXPECT_GT(Factorial(-10), 0);// EXPECT_EQ(expected, actual) is the same as//// EXPECT_TRUE((expected) == (actual))//// except that it will print both the expected value and the actual// value when the assertion fails.  This is very helpful for// debugging.  Therefore in this case EXPECT_EQ is preferred.//// On the other hand, EXPECT_TRUE accepts any Boolean expression,// and is thus more general.
}// Tests factorial of 0.
TEST(FactorialTest, Zero) {EXPECT_EQ(1, Factorial(0));
}// Tests factorial of positive numbers.
TEST(FactorialTest, Positive) {EXPECT_EQ(1, Factorial(1));EXPECT_EQ(2, Factorial(2));EXPECT_EQ(6, Factorial(3));EXPECT_EQ(40320, Factorial(8));
}// Tests IsPrime()
// Tests negative input.
TEST(IsPrimeTest, Negative) {// This test belongs to the IsPrimeTest test case.EXPECT_FALSE(IsPrime(-1));EXPECT_FALSE(IsPrime(-2));EXPECT_FALSE(IsPrime(INT_MIN));
}// Tests some trivial cases.
TEST(IsPrimeTest, Trivial) {EXPECT_FALSE(IsPrime(0));EXPECT_FALSE(IsPrime(1));EXPECT_TRUE(IsPrime(2));EXPECT_TRUE(IsPrime(3));
}// Tests positive input.
TEST(IsPrimeTest, Positive) {EXPECT_FALSE(IsPrime(4));EXPECT_TRUE(IsPrime(5));EXPECT_FALSE(IsPrime(6));EXPECT_TRUE(IsPrime(23));
}//Sample 2: This sample shows how to write a more complex unit test for a class
// that has multiple member functions.
//
// Usually, it's a good idea to have one test for each method in your
// class.  You don't have to do that exactly, but it helps to keep
// your tests organized.  You may also throw in additional tests as
// needed.// Tests the default c'tor.
TEST(MyString, DefaultConstructor) {const MyString s;// Asserts that s.c_string() returns NULL.//// If we write NULL instead of////   static_cast<const char *>(NULL)//// in this assertion, it will generate a warning on gcc 3.4.  The// reason is that EXPECT_EQ needs to know the types of its// arguments in order to print them when it fails.  Since NULL is// #defined as 0, the compiler will use the formatter function for// int to print it.  However, gcc thinks that NULL should be used as// a pointer, not an int, and therefore complains.//// The root of the problem is C++'s lack of distinction between the// integer number 0 and the null pointer constant.  Unfortunately,// we have to live with this fact.EXPECT_STREQ(NULL, s.c_string());EXPECT_EQ(0u, s.Length());
}const char kHelloString[] = "Hello, world!";// Tests the c'tor that accepts a C string.
TEST(MyString, ConstructorFromCString) {const MyString s(kHelloString);EXPECT_EQ(0, strcmp(s.c_string(), kHelloString));EXPECT_EQ(sizeof(kHelloString)/sizeof(kHelloString[0]) - 1,s.Length());
}// Tests the copy c'tor.
TEST(MyString, CopyConstructor) {const MyString s1(kHelloString);const MyString s2 = s1;EXPECT_EQ(0, strcmp(s2.c_string(), kHelloString));
}// Tests the Set method.
TEST(MyString, Set) {MyString s;s.Set(kHelloString);EXPECT_EQ(0, strcmp(s.c_string(), kHelloString));// Set should work when the input pointer is the same as the one// already in the MyString object.s.Set(s.c_string());EXPECT_EQ(0, strcmp(s.c_string(), kHelloString));// Can we set the MyString to NULL?s.Set(NULL);EXPECT_STREQ(NULL, s.c_string());
}//Sample 4: another basic example of using Google Test
// Tests the Increment() method.
TEST(Counter, Increment) {Counter c;// EXPECT_EQ() evaluates its arguments exactly once, so they// can have side effects.EXPECT_EQ(0, c.Increment());EXPECT_EQ(1, c.Increment());EXPECT_EQ(2, c.Increment());
}/*------------------------------------TEST_F macro------------------------------------*/
//Sample 3: In this example, we use a more advanced feature of Google Test called
// test fixture.
//
// A test fixture is a place to hold objects and functions shared by
// all tests in a test case.  Using a test fixture avoids duplicating
// the test code necessary to initialize and cleanup those common
// objects for each test.  It is also useful for defining sub-routines
// that your tests need to invoke a lot.
//
// The tests share the test fixture in the sense of code sharing, not
// data sharing.  Each test is given its own fresh copy of the
// fixture.  You cannot expect the data modified by one test to be
// passed on to another test, which is a bad idea.
//
// The reason for this design is that tests should be independent and
// repeatable.  In particular, a test should not fail as the result of
// another test's failure.  If one test depends on info produced by
// another test, then the two tests should really be one big test.
//
// The macros for indicating the success/failure of a test
// (EXPECT_TRUE, FAIL, etc) need to know what the current test is
// (when Google Test prints the test result, it tells you which test
// each failure belongs to).  Technically, these macros invoke a
// member function of the Test class.  Therefore, you cannot use them
// in a global function.  That's why you should put test sub-routines
// in a test fixture.// To use a test fixture, derive a class from testing::Test.
class QueueTest : public testing::Test {
protected:  // You should make the members protected s.t. they can be// accessed from sub-classes.// virtual void SetUp() will be called before each test is run.  You// should define it if you need to initialize the varaibles.// Otherwise, this can be skipped.virtual void SetUp() {q1_.Enqueue(1);q2_.Enqueue(2);q2_.Enqueue(3);}// virtual void TearDown() will be called after each test is run.// You should define it if there is cleanup work to do.  Otherwise,// you don't have to provide it.//// virtual void TearDown() {// }// A helper function that some test uses.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 != NULL; 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_;
};// When you have a test fixture, you define a test using TEST_F
// instead of TEST.
// Tests the default c'tor.
TEST_F(QueueTest, DefaultConstructor) {// You can access data in the test fixture here.EXPECT_EQ(0u, q0_.Size());
}// Tests Dequeue().
TEST_F(QueueTest, Dequeue) {int * n = q0_.Dequeue();EXPECT_TRUE(n == NULL);n = q1_.Dequeue();ASSERT_TRUE(n != NULL);EXPECT_EQ(1, *n);EXPECT_EQ(0u, q1_.Size());delete n;n = q2_.Dequeue();ASSERT_TRUE(n != NULL);EXPECT_EQ(2, *n);EXPECT_EQ(1u, q2_.Size());delete n;
}// Tests the Queue::Map() function.
TEST_F(QueueTest, Map) {MapTester(&q0_);MapTester(&q1_);MapTester(&q2_);
}// Sample 5: This sample teaches how to reuse a test fixture in multiple test
// cases by deriving sub-fixtures from it.
//
// When you define a test fixture, you specify the name of the test
// case that will use this fixture.  Therefore, a test fixture can
// be used by only one test case.
//
// Sometimes, more than one test cases may want to use the same or
// slightly different test fixtures.  For example, you may want to
// make sure that all tests for a GUI library don't leak important
// system resources like fonts and brushes.  In Google Test, you do
// this by putting the shared logic in a super (as in "super class")
// test fixture, and then have each test case use a fixture derived
// from this super fixture.// In this sample, we want to ensure that every test finishes within
// ~5 seconds.  If a test takes longer to run, we consider it a
// failure.
//
// We put the code for timing a test in a test fixture called
// "QuickTest".  QuickTest is intended to be the super fixture that
// other fixtures derive from, therefore there is no test case with
// the name "QuickTest".  This is OK.
//
// Later, we will derive multiple test fixtures from 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.virtual void SetUp() {start_time_ = time(NULL);}// TearDown() is invoked immediately after a test finishes.  Here we// check if the test was too slow.virtual void TearDown() {// Gets the time when the test finishesconst 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 startstime_t start_time_;
};// We derive a fixture named IntegerFunctionTest from the QuickTest
// fixture.  All tests using this fixture will be automatically
// required to be quick.
class IntegerFunctionTest : public QuickTest {// We don't need any more logic than already in the QuickTest fixture.// Therefore the body is empty.
};// Now we can write tests in the IntegerFunctionTest test case.// Tests Factorial()
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));
}// Tests IsPrime()
TEST_F(IntegerFunctionTest, IsPrime) {// Tests negative input.EXPECT_FALSE(IsPrime(-1));EXPECT_FALSE(IsPrime(-2));EXPECT_FALSE(IsPrime(INT_MIN));// Tests some trivial cases.EXPECT_FALSE(IsPrime(0));EXPECT_FALSE(IsPrime(1));EXPECT_TRUE(IsPrime(2));EXPECT_TRUE(IsPrime(3));// Tests positive input.EXPECT_FALSE(IsPrime(4));EXPECT_TRUE(IsPrime(5));EXPECT_FALSE(IsPrime(6));EXPECT_TRUE(IsPrime(23));
}// The next test case (named "QueueTest") also needs to be quick, so
// we derive another fixture from QuickTest.
//
// The QueueTest test fixture has some logic and shared objects in
// addition to what's in QuickTest already.  We define the additional
// stuff inside the body of the test fixture, as usual.
class QueueTest1 : 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_;
};// Now, let's write tests using the QueueTest fixture.// Tests the default constructor.
TEST_F(QueueTest1, DefaultConstructor) {EXPECT_EQ(0u, q0_.Size());
}// Tests Dequeue().
TEST_F(QueueTest1, Dequeue) {int* n = q0_.Dequeue();EXPECT_TRUE(n == NULL);n = q1_.Dequeue();EXPECT_TRUE(n != NULL);EXPECT_EQ(1, *n);EXPECT_EQ(0u, q1_.Size());delete n;n = q2_.Dequeue();EXPECT_TRUE(n != NULL);EXPECT_EQ(2, *n);EXPECT_EQ(1u, q2_.Size());delete n;
}/*-------------------TYPED_TEST macro and TYPED_TEST_P macro------------------*/
//Sample 6: This sample shows how to test common properties of multiple
// implementations of the same interface (aka interface tests).// First, we define some factory functions for creating instances of
// the implementations.  You may be able to skip this step if all your
// implementations can be constructed the same way.template <class T>
PrimeTable* CreatePrimeTable();template <>
PrimeTable* CreatePrimeTable<OnTheFlyPrimeTable>() {return new OnTheFlyPrimeTable;
}template <>
PrimeTable* CreatePrimeTable<PreCalculatedPrimeTable>() {return new PreCalculatedPrimeTable(10000);
}// Then we define a test fixture class template.
template <class T>
class PrimeTableTest : public testing::Test {
protected:// The ctor calls the factory function to create a prime table// implemented by T.PrimeTableTest() : table_(CreatePrimeTable<T>()) {}virtual ~PrimeTableTest() { delete table_; }// Note that we test an implementation via the base interface// instead of the actual implementation class.  This is important// for keeping the tests close to the real world scenario, where the// implementation is invoked via the base interface.  It avoids// got-yas where the implementation class has a method that shadows// a method with the same name (but slightly different argument// types) in the base interface, for example.PrimeTable* const table_;
};#if GTEST_HAS_TYPED_TESTusing testing::Types;// Google Test offers two ways for reusing tests for different types.
// The first is called "typed tests".  You should use it if you
// already know *all* the types you are gonna exercise when you write
// the tests.// To write a typed test case, first use
//
//   TYPED_TEST_CASE(TestCaseName, TypeList);
//
// to declare it and specify the type parameters.  As with TEST_F,
// TestCaseName must match the test fixture name.// The list of types we want to test.
typedef Types<OnTheFlyPrimeTable, PreCalculatedPrimeTable> Implementations;TYPED_TEST_CASE(PrimeTableTest, Implementations);// Then use TYPED_TEST(TestCaseName, TestName) to define a typed test,
// similar to TEST_F.
TYPED_TEST(PrimeTableTest, ReturnsFalseForNonPrimes) {// Inside the test body, you can refer to the type parameter by// TypeParam, and refer to the fixture class by TestFixture.  We// don't need them in this example.// Since we are in the template world, C++ requires explicitly// writing 'this->' when referring to members of the fixture class.// This is something you have to learn to live with.EXPECT_FALSE(this->table_->IsPrime(-5));EXPECT_FALSE(this->table_->IsPrime(0));EXPECT_FALSE(this->table_->IsPrime(1));EXPECT_FALSE(this->table_->IsPrime(4));EXPECT_FALSE(this->table_->IsPrime(6));EXPECT_FALSE(this->table_->IsPrime(100));
}TYPED_TEST(PrimeTableTest, ReturnsTrueForPrimes) {EXPECT_TRUE(this->table_->IsPrime(2));EXPECT_TRUE(this->table_->IsPrime(3));EXPECT_TRUE(this->table_->IsPrime(5));EXPECT_TRUE(this->table_->IsPrime(7));EXPECT_TRUE(this->table_->IsPrime(11));EXPECT_TRUE(this->table_->IsPrime(131));
}TYPED_TEST(PrimeTableTest, CanGetNextPrime) {EXPECT_EQ(2, this->table_->GetNextPrime(0));EXPECT_EQ(3, this->table_->GetNextPrime(2));EXPECT_EQ(5, this->table_->GetNextPrime(3));EXPECT_EQ(7, this->table_->GetNextPrime(5));EXPECT_EQ(11, this->table_->GetNextPrime(7));EXPECT_EQ(131, this->table_->GetNextPrime(128));
}// That's it!  Google Test will repeat each TYPED_TEST for each type
// in the type list specified in TYPED_TEST_CASE.  Sit back and be
// happy that you don't have to define them multiple times.#endif  // GTEST_HAS_TYPED_TEST#if GTEST_HAS_TYPED_TEST_Pusing testing::Types;// Sometimes, however, you don't yet know all the types that you want
// to test when you write the tests.  For example, if you are the
// author of an interface and expect other people to implement it, you
// might want to write a set of tests to make sure each implementation
// conforms to some basic requirements, but you don't know what
// implementations will be written in the future.
//
// How can you write the tests without committing to the type
// parameters?  That's what "type-parameterized tests" can do for you.
// It is a bit more involved than typed tests, but in return you get a
// test pattern that can be reused in many contexts, which is a big
// win.  Here's how you do it:// First, define a test fixture class template.  Here we just reuse
// the PrimeTableTest fixture defined earlier:template <class T>
class PrimeTableTest2 : public PrimeTableTest<T> {
};// Then, declare the test case.  The argument is the name of the test
// fixture, and also the name of the test case (as usual).  The _P
// suffix is for "parameterized" or "pattern".
TYPED_TEST_CASE_P(PrimeTableTest2);// Next, use TYPED_TEST_P(TestCaseName, TestName) to define a test,
// similar to what you do with TEST_F.
TYPED_TEST_P(PrimeTableTest2, ReturnsFalseForNonPrimes) {EXPECT_FALSE(this->table_->IsPrime(-5));EXPECT_FALSE(this->table_->IsPrime(0));EXPECT_FALSE(this->table_->IsPrime(1));EXPECT_FALSE(this->table_->IsPrime(4));EXPECT_FALSE(this->table_->IsPrime(6));EXPECT_FALSE(this->table_->IsPrime(100));
}TYPED_TEST_P(PrimeTableTest2, ReturnsTrueForPrimes) {EXPECT_TRUE(this->table_->IsPrime(2));EXPECT_TRUE(this->table_->IsPrime(3));EXPECT_TRUE(this->table_->IsPrime(5));EXPECT_TRUE(this->table_->IsPrime(7));EXPECT_TRUE(this->table_->IsPrime(11));EXPECT_TRUE(this->table_->IsPrime(131));
}TYPED_TEST_P(PrimeTableTest2, CanGetNextPrime) {EXPECT_EQ(2, this->table_->GetNextPrime(0));EXPECT_EQ(3, this->table_->GetNextPrime(2));EXPECT_EQ(5, this->table_->GetNextPrime(3));EXPECT_EQ(7, this->table_->GetNextPrime(5));EXPECT_EQ(11, this->table_->GetNextPrime(7));EXPECT_EQ(131, this->table_->GetNextPrime(128));
}// Type-parameterized tests involve one extra step: you have to
// enumerate the tests you defined:
REGISTER_TYPED_TEST_CASE_P(PrimeTableTest2,  // The first argument is the test case name.// The rest of the arguments are the test names.ReturnsFalseForNonPrimes, ReturnsTrueForPrimes, CanGetNextPrime);// At this point the test pattern is done.  However, you don't have
// any real test yet as you haven't said which types you want to run
// the tests with.// To turn the abstract test pattern into real tests, you instantiate
// it with a list of types.  Usually the test pattern will be defined
// in a .h file, and anyone can #include and instantiate it.  You can
// even instantiate it more than once in the same program.  To tell
// different instances apart, you give each of them a name, which will
// become part of the test case name and can be used in test filters.// The list of types we want to test.  Note that it doesn't have to be
// defined at the time we write the TYPED_TEST_P()s.
typedef Types<OnTheFlyPrimeTable, PreCalculatedPrimeTable>PrimeTableImplementations;
INSTANTIATE_TYPED_TEST_CASE_P(OnTheFlyAndPreCalculated,    // Instance namePrimeTableTest2,             // Test case namePrimeTableImplementations);  // Type list#endif  // GTEST_HAS_TYPED_TEST_P/*-----------------------------TEST_P macro--------------------------------*/
//Sample 7: This sample shows how to test common properties of multiple
// implementations of an interface (aka interface tests) using
// value-parameterized tests. Each test in the test case has
// a parameter that is an interface pointer to an implementation
// tested.#if GTEST_HAS_PARAM_TESTusing ::testing::TestWithParam;
using ::testing::Values;// As a general rule, to prevent a test from affecting the tests that come
// after it, you should create and destroy the tested objects for each test
// instead of reusing them.  In this sample we will define a simple factory
// function for PrimeTable objects.  We will instantiate objects in test's
// SetUp() method and delete them in TearDown() method.
typedef PrimeTable* CreatePrimeTableFunc();PrimeTable* CreateOnTheFlyPrimeTable() {return new OnTheFlyPrimeTable();
}template <size_t max_precalculated>
PrimeTable* CreatePreCalculatedPrimeTable() {return new PreCalculatedPrimeTable(max_precalculated);
}// Inside the test body, fixture constructor, SetUp(), and TearDown() you
// can refer to the test parameter by GetParam().  In this case, the test
// parameter is a factory function which we call in fixture's SetUp() to
// create and store an instance of PrimeTable.
class PrimeTableTest1 : public TestWithParam<CreatePrimeTableFunc*> {
public:virtual ~PrimeTableTest1() { delete table_; }virtual void SetUp() { table_ = (*GetParam())(); }virtual void TearDown() {delete table_;table_ = NULL;}protected:PrimeTable* table_;
};TEST_P(PrimeTableTest1, ReturnsFalseForNonPrimes) {EXPECT_FALSE(table_->IsPrime(-5));EXPECT_FALSE(table_->IsPrime(0));EXPECT_FALSE(table_->IsPrime(1));EXPECT_FALSE(table_->IsPrime(4));EXPECT_FALSE(table_->IsPrime(6));EXPECT_FALSE(table_->IsPrime(100));
}TEST_P(PrimeTableTest1, ReturnsTrueForPrimes) {EXPECT_TRUE(table_->IsPrime(2));EXPECT_TRUE(table_->IsPrime(3));EXPECT_TRUE(table_->IsPrime(5));EXPECT_TRUE(table_->IsPrime(7));EXPECT_TRUE(table_->IsPrime(11));EXPECT_TRUE(table_->IsPrime(131));
}TEST_P(PrimeTableTest1, CanGetNextPrime) {EXPECT_EQ(2, table_->GetNextPrime(0));EXPECT_EQ(3, table_->GetNextPrime(2));EXPECT_EQ(5, table_->GetNextPrime(3));EXPECT_EQ(7, table_->GetNextPrime(5));EXPECT_EQ(11, table_->GetNextPrime(7));EXPECT_EQ(131, table_->GetNextPrime(128));
}// In order to run value-parameterized tests, you need to instantiate them,
// or bind them to a list of values which will be used as test parameters.
// You can instantiate them in a different translation module, or even
// instantiate them several times.
//
// Here, we instantiate our tests with a list of two PrimeTable object
// factory functions:
INSTANTIATE_TEST_CASE_P(OnTheFlyAndPreCalculated,PrimeTableTest1,Values(&CreateOnTheFlyPrimeTable, &CreatePreCalculatedPrimeTable<1000>));#else// Google Test may not support value-parameterized tests with some
// compilers. If we use conditional compilation to compile out all
// code referring to the gtest_main library, MSVC linker will not link
// that library at all and consequently complain about missing entry
// point defined in that library (fatal error LNK1561: entry point
// must be defined). This dummy test keeps gtest_main linked in.
TEST(DummyTest, ValueParameterizedTestsAreNotSupportedOnThisPlatform) {}#endif  // GTEST_HAS_PARAM_TEST// Sample 8: This sample shows how to test code relying on some global flag variables.
// Combine() helps with generating all possible combinations of such flags,
// and each test is given one combination as a parameter.#if GTEST_HAS_COMBINE// Suppose we want to introduce a new, improved implementation of PrimeTable
// which combines speed of PrecalcPrimeTable and versatility of
// OnTheFlyPrimeTable (see prime_tables.h). Inside it instantiates both
// PrecalcPrimeTable and OnTheFlyPrimeTable and uses the one that is more
// appropriate under the circumstances. But in low memory conditions, it can be
// told to instantiate without PrecalcPrimeTable instance at all and use only
// OnTheFlyPrimeTable.
class HybridPrimeTable : public PrimeTable {
public:HybridPrimeTable(bool force_on_the_fly, int max_precalculated): on_the_fly_impl_(new OnTheFlyPrimeTable),precalc_impl_(force_on_the_fly ? NULL :new PreCalculatedPrimeTable(max_precalculated)),max_precalculated_(max_precalculated) {}virtual ~HybridPrimeTable() {delete on_the_fly_impl_;delete precalc_impl_;}virtual bool IsPrime(int n) const {if (precalc_impl_ != NULL && n < max_precalculated_)return precalc_impl_->IsPrime(n);elsereturn on_the_fly_impl_->IsPrime(n);}virtual int GetNextPrime(int p) const {int next_prime = -1;if (precalc_impl_ != NULL && p < max_precalculated_)next_prime = precalc_impl_->GetNextPrime(p);return next_prime != -1 ? next_prime : on_the_fly_impl_->GetNextPrime(p);}private:OnTheFlyPrimeTable* on_the_fly_impl_;PreCalculatedPrimeTable* precalc_impl_;int max_precalculated_;
};using ::testing::TestWithParam;
using ::testing::Bool;
using ::testing::Values;
using ::testing::Combine;// To test all code paths for HybridPrimeTable we must test it with numbers
// both within and outside PreCalculatedPrimeTable's capacity and also with
// PreCalculatedPrimeTable disabled. We do this by defining fixture which will
// accept different combinations of parameters for instantiating a
// HybridPrimeTable instance.
class PrimeTableTest3 : public TestWithParam< ::std::tr1::tuple<bool, int> > {
protected:virtual void SetUp() {// This can be written as//// bool force_on_the_fly;// int max_precalculated;// tie(force_on_the_fly, max_precalculated) = GetParam();//// once the Google C++ Style Guide allows use of ::std::tr1::tie.//bool force_on_the_fly = ::std::tr1::get<0>(GetParam());int max_precalculated = ::std::tr1::get<1>(GetParam());table_ = new HybridPrimeTable(force_on_the_fly, max_precalculated);}virtual void TearDown() {delete table_;table_ = NULL;}HybridPrimeTable* table_;
};TEST_P(PrimeTableTest3, ReturnsFalseForNonPrimes) {// Inside the test body, you can refer to the test parameter by GetParam().// In this case, the test parameter is a PrimeTable interface pointer which// we can use directly.// Please note that you can also save it in the fixture's SetUp() method// or constructor and use saved copy in the tests.EXPECT_FALSE(table_->IsPrime(-5));EXPECT_FALSE(table_->IsPrime(0));EXPECT_FALSE(table_->IsPrime(1));EXPECT_FALSE(table_->IsPrime(4));EXPECT_FALSE(table_->IsPrime(6));EXPECT_FALSE(table_->IsPrime(100));
}TEST_P(PrimeTableTest3, ReturnsTrueForPrimes) {EXPECT_TRUE(table_->IsPrime(2));EXPECT_TRUE(table_->IsPrime(3));EXPECT_TRUE(table_->IsPrime(5));EXPECT_TRUE(table_->IsPrime(7));EXPECT_TRUE(table_->IsPrime(11));EXPECT_TRUE(table_->IsPrime(131));
}TEST_P(PrimeTableTest3, CanGetNextPrime) {EXPECT_EQ(2, table_->GetNextPrime(0));EXPECT_EQ(3, table_->GetNextPrime(2));EXPECT_EQ(5, table_->GetNextPrime(3));EXPECT_EQ(7, table_->GetNextPrime(5));EXPECT_EQ(11, table_->GetNextPrime(7));EXPECT_EQ(131, table_->GetNextPrime(128));
}// In order to run value-parameterized tests, you need to instantiate them,
// or bind them to a list of values which will be used as test parameters.
// You can instantiate them in a different translation module, or even
// instantiate them several times.
//
// Here, we instantiate our tests with a list of parameters. We must combine
// all variations of the boolean flag suppressing PrecalcPrimeTable and some
// meaningful values for tests. We choose a small value (1), and a value that
// will put some of the tested numbers beyond the capability of the
// PrecalcPrimeTable instance and some inside it (10). Combine will produce all
// possible combinations.
INSTANTIATE_TEST_CASE_P(MeaningfulTestParameters,PrimeTableTest3,Combine(Bool(), Values(1, 10)));#else// Google Test may not support Combine() with some compilers. If we
// use conditional compilation to compile out all code referring to
// the gtest_main library, MSVC linker will not link that library at
// all and consequently complain about missing entry point defined in
// that library (fatal error LNK1561: entry point must be
// defined). This dummy test keeps gtest_main linked in.
TEST(DummyTest, CombineIsNotSupportedOnThisPlatform) {}#endif  // GTEST_HAS_COMBINEint main (int argc, char* argv[])
{testing::InitGoogleTest(&argc, argv);//::testing::GTEST_FLAG(filter) = "IsPrimeTest.*:FactorialTest.*";return RUN_ALL_TESTS();return 0;
}#endif #if defined BRANCH_2
// Sample 9: This sample shows how to use Google Test listener API to implement
// an alternative console output and how to use the UnitTest reflection API
// to enumerate test cases and tests and to inspect their results.
using ::testing::EmptyTestEventListener;
using ::testing::InitGoogleTest;
using ::testing::Test;
using ::testing::TestCase;
using ::testing::TestEventListeners;
using ::testing::TestInfo;
using ::testing::TestPartResult;
using ::testing::UnitTest;namespace {// Provides alternative output mode which produces minimal amount of// information about tests.class TersePrinter : public EmptyTestEventListener {private:// Called before any test activity starts.virtual void OnTestProgramStart(const UnitTest& /* unit_test */) {}// Called after all test activities have ended.virtual void OnTestProgramEnd(const UnitTest& unit_test) {fprintf(stdout, "TEST %s\n", unit_test.Passed() ? "PASSED" : "FAILED");fflush(stdout);}// Called before a test starts.virtual void OnTestStart(const TestInfo& test_info) {fprintf(stdout,"*** Test %s.%s starting.\n",test_info.test_case_name(),test_info.name());fflush(stdout);}// Called after a failed assertion or a SUCCEED() invocation.virtual void OnTestPartResult(const TestPartResult& test_part_result) {fprintf(stdout,"%s in %s:%d\n%s\n",test_part_result.failed() ? "*** Failure" : "Success",test_part_result.file_name(),test_part_result.line_number(),test_part_result.summary());fflush(stdout);}// Called after a test ends.virtual void OnTestEnd(const TestInfo& test_info) {fprintf(stdout,"*** Test %s.%s ending.\n",test_info.test_case_name(),test_info.name());fflush(stdout);}};  // class TersePrinterTEST(CustomOutputTest, PrintsMessage) {printf("Printing something from the test body...\n");}TEST(CustomOutputTest, Succeeds) {SUCCEED() << "SUCCEED() has been invoked from here";}TEST(CustomOutputTest, Fails) {EXPECT_EQ(1, 2)<< "This test fails in order to demonstrate alternative failure messages";}}  // namespaceint main(int argc, char **argv) {InitGoogleTest(&argc, argv);bool terse_output = false;if (argc > 1 && strcmp(argv[1], "--terse_output") == 0 )terse_output = true;elseprintf("%s\n", "Run this program with --terse_output to change the way ""it prints its output.");UnitTest& unit_test = *UnitTest::GetInstance();// If we are given the --terse_output command line flag, suppresses the// standard output and attaches own result printer.if (terse_output) {TestEventListeners& listeners = unit_test.listeners();// Removes the default console output listener from the list so it will// not receive events from Google Test and won't print any output. Since// this operation transfers ownership of the listener to the caller we// have to delete it as well.delete listeners.Release(listeners.default_result_printer());// Adds the custom output listener to the list. It will now receive// events from Google Test and print the alternative output. We don't// have to worry about deleting it since Google Test assumes ownership// over it after adding it to the list.listeners.Append(new TersePrinter);}int ret_val = RUN_ALL_TESTS();// This is an example of using the UnitTest reflection API to inspect test// results. Here we discount failures from the tests we expected to fail.int unexpectedly_failed_tests = 0;for (int i = 0; i < unit_test.total_test_case_count(); ++i) {const TestCase& test_case = *unit_test.GetTestCase(i);for (int j = 0; j < test_case.total_test_count(); ++j) {const TestInfo& test_info = *test_case.GetTestInfo(j);// Counts failed tests that were not meant to fail (those without// 'Fails' in the name).if (test_info.result()->Failed() &&strcmp(test_info.name(), "Fails") != 0) {unexpectedly_failed_tests++;}}}// Test that were meant to fail should not affect the test program outcome.if (unexpectedly_failed_tests == 0)ret_val = 0;return ret_val;
}#endif#if defined BRANCH_3
// Sample 10: This sample shows how to use Google Test listener API to implement
// a primitive leak checker.
using ::testing::EmptyTestEventListener;
using ::testing::InitGoogleTest;
using ::testing::Test;
using ::testing::TestCase;
using ::testing::TestEventListeners;
using ::testing::TestInfo;
using ::testing::TestPartResult;
using ::testing::UnitTest;namespace {// We will track memory used by this class.class Water {public:// Normal Water declarations go here.// operator new and operator delete help us control water allocation.void* operator new(size_t allocation_size) {allocated_++;return malloc(allocation_size);}void operator delete(void* block, size_t /* allocation_size */) {allocated_--;free(block);}static int allocated() { return allocated_; }private:static int allocated_;};int Water::allocated_ = 0;// This event listener monitors how many Water objects are created and// destroyed by each test, and reports a failure if a test leaks some Water// objects. It does this by comparing the number of live Water objects at// the beginning of a test and at the end of a test.class LeakChecker : public EmptyTestEventListener {private:// Called before a test starts.virtual void OnTestStart(const TestInfo& /* test_info */) {initially_allocated_ = Water::allocated();}// Called after a test ends.virtual void OnTestEnd(const TestInfo& /* test_info */) {int difference = Water::allocated() - initially_allocated_;// You can generate a failure in any event handler except// OnTestPartResult. Just use an appropriate Google Test assertion to do// it.EXPECT_LE(difference, 0) << "Leaked " << difference << " unit(s) of Water!";}int initially_allocated_;};TEST(ListenersTest, DoesNotLeak) {Water* water = new Water;delete water;}// This should fail when the --check_for_leaks command line flag is// specified.TEST(ListenersTest, LeaksWater) {Water* water = new Water;EXPECT_TRUE(water != NULL);}}  // namespaceint main(int argc, char **argv) {InitGoogleTest(&argc, argv);bool check_for_leaks = false;if (argc > 1 && strcmp(argv[1], "--check_for_leaks") == 0 )check_for_leaks = true;elseprintf("%s\n", "Run this program with --check_for_leaks to enable ""custom leak checking in the tests.");// If we are given the --check_for_leaks command line flag, installs the// leak checker.if (check_for_leaks) {TestEventListeners& listeners = UnitTest::GetInstance()->listeners();// Adds the leak checker to the end of the test event listener list,// after the default text output printer and the default XML report// generator.//// The order is important - it ensures that failures generated in the// leak checker's OnTestEnd() method are processed by the text and XML// printers *before* their OnTestEnd() methods are called, such that// they are attributed to the right test. Remember that a listener// receives an OnXyzStart event *after* listeners preceding it in the// list received that event, and receives an OnXyzEnd event *before*// listeners preceding it.//// We don't need to worry about deleting the new listener later, as// Google Test will do it.listeners.Append(new LeakChecker);}return RUN_ALL_TESTS();
}#endif


相关文章:

新浪微博推广网站的一些实践体会

本以为微博推广很难&#xff0c;每天都要刷粉刷内容的&#xff0c;也本以为做微博推广也很简单&#xff0c;一不卖产品、二不卖服务的&#xff0c;目的单纯灵活性强些&#xff0c;做了之后才发现都不是那么回事&#xff0c;微博虽然也过了“火了”&#xff0c;但新媒体还真是不…

AI和大数据如何落地智能城市?京东城市这6篇论文必读 | KDD 2019

来源 | 京东城市&#xff08;ID: icity-jd&#xff09;作为世界数据挖掘领域的最高级别的学术会议&#xff0c;ACM SIGKDD&#xff08;国际数据挖掘与知识发现大会&#xff0c;简称 KDD&#xff09;将于 2019 年 8 月 4 日—8 日在美国阿拉斯加州安克雷奇市举行。自 1995 年以来…

OSError: Could not find library geos_c or load any of its variants ['libgeos_c.so.1', 'libgeos_c.so

OSError: Could not find library geos_c or load any of its variants [libgeos_c.so.1, libgeos_c.so 解决&#xff1a; sudo vim /etc/ld.so.conf 添加&#xff1a;/opt/source/geos-3.5.0/build/lib sudo ldconfig

五分钟搭建BERT服务,实现1000+QPS​,这个Service-Streamer做到了

作者 | 刘欣简介&#xff1a;刘欣&#xff0c;Meteorix&#xff0c;毕业于华中科技大学&#xff0c;前网易游戏技术总监&#xff0c;现任香侬科技算法架构负责人。之前专注游戏引擎工具架构和自动化领域&#xff0c;2018年在GDC和GoogleIO开源Airtest自动化框架&#xff0c;广泛…

Nagios+pnp4nagios+rrdtool 安装配置为nagios添加自定义插件(三)

nagios博大精深&#xff0c;可以以shell、perl等语句为nagios写插件&#xff0c;来满足自己监控的需要。本文写mysql中tps、qps的插件&#xff0c;并把收集到的结果以图形形式展现出来&#xff0c;这样输出的结果就有一定的要求了。 编写插件tps qps check_qps 插件如下内容 #…

OpenSSL简介及在Windows、Linux、Mac系统上的编译步骤

OpenSSL介绍&#xff1a;OpenSSL是一个强大的安全套接字层密码库&#xff0c;囊括主要的密码算法、常用的密钥和证书封装管理功能及SSL协议&#xff0c;并提供丰富的应用程序供测试或其它目的使用。 SSL是SecureSockets Layer(安全套接层协议)的缩写&#xff0c;可以在Interne…

Guava Cache本地缓存在 Spring Boot应用中的实践

概述 在如今高并发的互联网应用中&#xff0c;缓存的地位举足轻重&#xff0c;对提升程序性能帮助不小。而 3.x开始的 Spring也引入了对 Cache的支持&#xff0c;那对于如今发展得如火如荼的 Spring Boot来说自然也是支持缓存特性的。当然 Spring Boot默认使用的是 SimpleCache…

Windows 8.1 Preview(Windows Blue)预览版简体中文官方下载(ISO完整版镜像)

Windows 8.1是微软继Windows 8以来的又一全新力作&#xff0c;又名Windows Blue&#xff08;视窗蓝&#xff0c;专注蓝屏30年&#xff09;&#xff0c;个人觉得Win8还是比较流畅的但大众始终觉得还是有很多需要改进或者改善的&#xff0c;如今微软为了迎合大众需求对Win8进行升…

Linux下编辑器vi/vim的使用介绍

vi编辑器是所有Unix及Linux系统下标准的编辑器。对Unix及Linux系统的任何版本&#xff0c;vi编辑器是完全相同的。 基本上vi可以分为三种状态&#xff0c;分别是命令模式(commandmode)、插入模式(insert mode)和底行模式(last line mode)&#xff0c;各模式的功能为&#xff1…

Clojure程序设计

《Clojure程序设计》基本信息作者&#xff1a; (美)Stuart Halloway Aaron Bedra [作译者介绍]出版社&#xff1a;人民邮电出版社ISBN&#xff1a;9787115308474上架时间&#xff1a;2013-3-1出版日期&#xff1a;2013 年3月开本&#xff1a;16开页码&#xff1a;230版次&#…

重磅!AI Top 30+案例评选正式启动

2019 年&#xff0c;人工智能应用落地的重要性正在逐步得到验证&#xff0c;这是关乎企业生死攸关的一环。科技巨头、AI 独角兽还有起于草莽的创业公司在各领域进行着一场多方角斗。进行平台布局的科技巨头们&#xff0c;正在加快承载企业部署 AI 应用的步伐&#xff0c;曾经无…

直播回顾 | 关于Apollo 5.0控制在环仿真技术的分享

Apollo 用于模型验证和测试的基于 Web 的仿真平台 Dreamland 已经更新到能使用更强大的场景编辑器和环控制模拟。基于 Apollo 流水线和机器学习的动力学模型&#xff0c;复杂度较高&#xff0c;同时基于 AI 的全景数据建模&#xff0c;模型精细度高&#xff0c;误差比传统方式可…

eclipes 安装 pytdev,svn,插件

1&#xff0c; python pydevhttp://pydev.org/updates2, svnhttp://subclipse.tigris.org/update3, 推荐http://subclipse.tigris.org/update_1.10.x 转载于:https://blog.51cto.com/swq499809608/1240873

FFmpeg简介及在vc2010下编译步骤

FFmpeg是一个开源的多媒体库&#xff0c;最新版本是2.4.3&#xff0c;它的License是LGPL或GPL。FFmpeg可以用来记录、转换数字音频、视频&#xff0c;并能将其转换为流的开源计算机程序。它包括了音/视频编码库libavcodec。FFmpeg是在Linux下开发出来的&#xff0c;但它可以在包…

医院六级电子病历建设思路及要点

产生背景 在医院电子病历信息化发展的过程中&#xff0c;先后经历了纸质病历、电子病历、结构化电子病历以及具有全医疗过程管理能力的电子病历四个阶段。临床业务需求质量的逐步提升&#xff0c;标准规范的逐步细化&#xff0c;互联网战略的落地实施&#xff0c;无疑对目前电子…

上手必备!不可错过的TensorFlow、PyTorch和Keras样例资源

作者 | 黄海广来源 | 机器学习初学者&#xff08;ID: ai-start-com&#xff09;TensorFlow、Keras和PyTorch是目前深度学习的主要框架&#xff0c;也是入门深度学习必须掌握的三大框架&#xff0c;但是官方文档相对内容较多&#xff0c;初学者往往无从下手。本人从github里搜到…

Linux下gdb调试工具的使用

gdb是GNU开源组织发布的一个强大的Linux下的程序调试工具。 gdb主要完成四个方面的功能&#xff1a;(1)、启动你的程序&#xff0c;可以按照你的自定义的要求随心所欲的运行程序&#xff1b;(2)、可让被调试的程序在你所指定的调试的断点处停住(断点可以是条件表达式)&#xf…

UESTC 1726 整数划分(母函数)

题目链接&#xff1a;http://222.197.181.5/problem.php?pid1726 题意&#xff1a;求n的划分数。一种划分方案中不能有相同的数字。 思路&#xff1a;(1x)(1x^2)(1x^3)……(1x^1000). int f[N];void init() {f[1]1;int a[N]{0};a[0]1; a[1]1;int i,j;for(i2;i<1000;i){for(…

JS nodeType返回类型

JS nodeType返回类型 前几天朋友正好问道 这个 js的nodeType是个什么概念&#xff08;做浏览器底层的&#xff09;正好遇到这篇文章可以向大家解释下 将HTML DOM中几个容易常用的属性做下记录&#xff1a; nodeName、nodeValue 以及 nodeType 包含有关于节点的信息。 nodeName …

C# 获取指定目录下所有文件信息、移动目录、拷贝目录

/// <summary>/// 返回指定目录下的所有文件信息/// </summary>/// <param name"strDirectory"></param>/// <returns></returns>public List<FileInfo> GetAllFilesInDirectory(string strDirectory){List<FileInfo&g…

文件夹浏览(SHBrowseForFolder)

from http://www.cnblogs.com/Clingingboy/archive/2011/04/16/2018284.html 一.首先要为SHBrowseForFolder准备一个结构体BROWSEINFO typedef struct _browseinfoW {HWND hwndOwner;PCIDLIST_ABSOLUTE pidlRoot;LPWSTR pszDisplayName; // Return display…

技术新贵:RPA与NLP技术的结合与应用

什么是 RPA&#xff08;Robotic Process Automation&#xff09;&#xff1f;机器人流程自动化&#xff08;RPA&#xff09;是一种自动化工具&#xff0c;用于创建软件机器人的虚拟劳动力&#xff0c;从而优化和降低企业中端到端业务流程的成本。RPA 可以翻译成机器人流程自动化…

API Sanity Checker在Ubuntu中的使用

API Sanity Checker是一个自动生成单元测试用例的工具&#xff0c;可用于链接测试。它可用于三大桌面平台&#xff0c;下面简单介绍它在Linux下的使用步骤&#xff1a;1. 从http://ispras.linuxbase.org/index.php/API_Sanity_Autotest 下载最新的api-sanity-checker-1.98…

手动脱壳—dump与重建输入表(转)

文章中用到的demo下载地址&#xff1a; http://download.csdn.net/detail/ccnyou/4540254 附件中包含demo以及文章word原稿 用到工具: Ollydbg LordPE ImportREC 这些工具请自行下载准备 Dump原理这里也不多做描述&#xff0c;想要了解google it&#xff01;常见的dump软件有Lo…

如何用RNN生成莎士比亚风格的句子?(文末赠书)

作者 | 李理&#xff0c;环信人工智能研发中心vp&#xff0c;十多年自然语言处理和人工智能研发经验。主持研发过多款智能硬件的问答和对话系统&#xff0c;负责环信中文语义分析开放平台和环信智能机器人的设计与研发。来源 | 《深度学习理论与实战&#xff1a;基础篇》基本概…

图像相似度计算之哈希值方法OpenCV实现

感知哈希算法(perceptual hash algorithm)&#xff0c;它的作用是对每张图像生成一个“指纹”(fingerprint)字符串&#xff0c;然后比较不同图像的指纹。结果越接近&#xff0c;就说明图像越相似。 实现步骤&#xff1a; 1. 缩小尺寸&#xff1a;将图像缩小到8*8的尺寸&am…

七夕大礼包:26个AI学习资源送给你!

整理 | Jane出品 | AI科技大本营&#xff08;ID&#xff1a;rgznai100&#xff09;免费的在线学习课程一直是大多数人学习 AI 知识和技能的方式之一。今天&#xff0c;基于 Github 上一位小姐姐 Chip Huyen 分享的 10 门机器学习课程&#xff0c;AI科技大本营将这份收藏大礼包进…

HTML Inspector – 帮助你编写高质量的 HTML 代码

HTML Inspector 是一款代码质量检测工具&#xff0c;帮助你编写更优秀的 HTML 代码。HTML Inspector 使用 JavaScript 编写&#xff0c;运行在浏览器中&#xff0c;是最好的 HTML 代码检测工具。 您可能感兴趣的相关文章Metronic – 赞&#xff01;Bootstrap 响应式后台管理模板…

Git简介以及与SVN的区别

Git是由著名Linux内核(Kernel)开发者Linus Torvalds为了便利维护Linux而开发的。 Git是一个分布式的版本控制系统。作为一个分布式的版本控制系统&#xff0c;在Git中并不存在主库这样的概念&#xff0c;每一份复制出的库都可以独立使用&#xff0c;任何两个库之间的不一致之处…

java集合中某一个元素出现的次数

int count Collections.frequency(list, key); java的内置方法转载于:https://www.cnblogs.com/wysAC666/p/10252676.html