gtest它是一种跨平台的(Liunx、Mac OS X、Windows、Cygwin、Windows CE and Symbian)的C++测试框架。有google该公司宣布。

gtest台上为编写C++測试而生成的。

name=gtest-1.7.0.zip&can=2&q">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.slnproject,须要进行转换,生成gtest、gtest_main、gtest_prod_test、gtest_unittest四个project;(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’中新建一个Testgtestproject;(2)、新加一个fun.h文件,此文件内容为:

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

(3)、改动project属性: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();
}

运行此project就可以输出相关信息。改动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的样例。我将其加入到一个project中,便于查看:

1. 新建一个gtestSamples的project;

2. 此project下的文件包括:(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'tor
MyString(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 numbers
if (n <= 1) return false; // Trivial case 2: even numbers
if (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 3
for (int i = 3; ; i += 2) {
// We only have to try i up to the squre root of n
if (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 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_;
}; // 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_TEST using 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_P using 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 name
PrimeTableTest2, // Test case name
PrimeTableImplementations); // 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_TEST using ::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);
else
return 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_COMBINE int 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 TersePrinter TEST(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";
} } // namespace int main(int argc, char **argv) {
InitGoogleTest(&argc, argv); bool terse_output = false;
if (argc > 1 && strcmp(argv[1], "--terse_output") == 0 )
terse_output = true;
else
printf("%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);
} } // namespace int 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;
else
printf("%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

版权声明:本文博客原创文章,博客,未经同意,不得转载。

gtest简短,简单易用的更多相关文章

  1. FineBI:一个简单易用的自助BI工具

    过去,有关企业数据分析的重担都压在IT部门,传统BI分析更多面向的是具有IT背景的人员.但随着业务分析需求的增加,很多公司都希望为业务用户提供自助分析服务,将分析工作落实到业务人员手中.但同时,分析工 ...

  2. DataAccess通用数据库访问类,简单易用,功能强悍

    以下是我编写的DataAccess通用数据库访问类,简单易用,支持:内联式创建多个参数.支持多事务提交.支持参数复用.支持更换数据库类型,希望能帮到大家,若需支持查出来后转换成实体,可以自行扩展dat ...

  3. 快速上手seajs——简单易用Seajs

    快速上手seajs——简单易用Seajs   原文  http://www.cnblogs.com/xjchenhao/p/4021775.html 主题 SeaJS 简易手册 http://yslo ...

  4. [.net 面向对象程序设计进阶] (22) 团队开发利器(一)简单易用的代码管理工具VSS

    [.net 面向对象程序设计进阶] (22) 团队开发利器(一)简单易用的代码管理工具VSS 本篇要点:在进阶篇快要结束的时候说说源代码管理器,我们的开发,不是一个人可以完成的事,团队协作很重要,而且 ...

  5. 设计与开发一款简单易用的Web报表工具(支持常用关系数据及hadoop、hbase等)

    EasyReport是一个简单易用的Web报表工具(支持Hadoop,HBase及各种关系型数据库),它的主要功能是把SQL语句查询出的行列结构转换成HTML表格(Table),并支持表格的跨行(Ro ...

  6. 分享一个简单易用的RPC开源项目—Tatala

    http://zijan.iteye.com/blog/2041894 这个项目最早(2008年)是用于一个网络游戏的Cache Server,以及一个电子商务的Web Session服务.后来不断增 ...

  7. ZOOM - 简单易用的 jQuery 照片相册插件

    jQuery 最令人印象深刻的应用之一就是对图片的处理,它可以让帮助你在你的项目中加入一些让人惊叹的图片切换效果.ZOOM 是一款全屏效果的 jQuery 图片切换展示插件,支持键盘前后按键切换,支持 ...

  8. BasicModal - 简单易用的现代 Web App 弹窗

    BasicModal 是为现代 Web 应用程序打造的弹窗系统.它包括所有你需要显示的信息,问题或接收用户的输入.这里的弹窗还可以链接起来,所以你可以很容易地建立一个预定义顺序的安装帮助或显示对话框. ...

  9. PNotify – 简单易用的 JS 通知,消息提示插件

    PNotify 是一个 JavaScript 通知插件,前身为 Pines Notify.它旨在提供无与伦比的灵活性,同时很容易使用.它可以提供无阻塞的通知,允许用户无需关闭通知或者提示信息就可以点击 ...

  10. Echo.js – 简单易用的 JavaScript 图片延迟加载插件

    Echo.js 是一个独立的延迟加载图片的 JavaScript 插件.Echo.js 不依赖第三方库,压缩后不到1KB大小. 延迟加载是提高网页首屏显示速度的一种很有效的方法,当图片元素进入窗口可视 ...

随机推荐

  1. 简单工厂 VS 工厂方法 VS 抽象工厂

    说到设计模式.自然少不了简单工厂模式.工厂方法和抽象工厂这三姐妹. 它们之间可谓是各有所长,术业专攻啊!这篇博客来简单的梳理一下三者之间的关系. 那么工厂又是什么意思呢?结合三者的特点,我觉得能够这样 ...

  2. Web测试基于实际测试的功能测试点总结--转载

    文章来源:http://www.51testing.com/html/99/n-854599.html 好文章就该记录一下\(^o^)/~ 一.页面链接检查:测试每一个链接是否都有对应的页面,并且页面 ...

  3. SSO(Single Sign On)系列(一)--SSO简单介绍

    任何类型的站点,到达一定规模之后一定会存在这种问题:比方我们有N个系统.传统方式下我们就须要有N对不同的username和password,本来这些系统的开发都能为我们带来良好的效益,用户在用的时候并 ...

  4. erlang如何有效地监视大量的并发连接

    阅读erlang一些开源web框架RabbitMQ.Ranch,他们使用多个进程在同一时间accept一socket.以这样的方式,使socketport监控共享很多其他的机会调度工作,但,在erla ...

  5. Red Gate系列之四 SQL Data Compare 10.2.0.885 Edition 数据比较同步工具 完全破解+使用教程

    原文:Red Gate系列之四 SQL Data Compare 10.2.0.885 Edition 数据比较同步工具 完全破解+使用教程 Red Gate系列之四 SQL Data Compare ...

  6. Java EE (2) -- Java EE 6 Enterprise JavaBeans Developer Certified Expert(1z0-895)

    Introduction to Java EE Gain an understanding of the Java Platform, Enterprise Edition (Java EE) Exa ...

  7. cocos2d-x V3.0 呼叫加速度计 Acceleration

    今天克服了一个问题,我觉得非常酷 哈哈. 今天得到解决cocos2d-x 3.0 呼叫重力加速器问题,上网查了很多资料 发现是不够,不解决这个问题,我不知道如果我使用3.0 这一问题的版本号,但是,这 ...

  8. C# 隐藏 Windows Phone 侦错模式中萤幕右上角的数据条(模拟器、实机可用),截图好方便。

    原文:C# 隐藏 Windows Phone 侦错模式中萤幕右上角的数据条(模拟器.实机可用),截图好方便. 一般我们在开发Windows Phone App时,会使用模拟器或是实体的手机开发,在Vi ...

  9. Android SQLite 数据库 增删改查操作

    Android SQLite 数据库 增删改查操作 转载▼ 一.使用嵌入式关系型SQLite数据库存储数据 在Android平台上,集成了一个嵌入式关系型数据库--SQLite,SQLite3支持NU ...

  10. Java 抽象工厂模式

    抽象工厂模式(Abstract Factory Pattern)是工厂方法模式的进一步抽象,其英文原话"Provide an interface for creating families ...