`
郭广川
  • 浏览: 67073 次
  • 性别: Icon_minigender_1
  • 来自: 河北
社区版块
存档分类
最新评论

Google Test测试框架自带Sample案例注释翻译

阅读更多

      有一段时间没写博客了,前些时间闲下来看了下google test(gtest)测试框架自带的sample测试样例,感觉还不错,就对里面的注释进行了相关翻译,在此做个标录,对测试流程、方法和设计的理解会有些帮助,方便日后重新查阅,有兴趣的同志不妨看一下

相关说明:

     1、项目工程可到附件中下载

     2、项目工程在visual studio2005环境下编译运行的

     3、对于想对gtest有进一步了解的通知,可参考金山公司一个前辈的gtest技术博客http://www.cnblogs.com/coderzh/archive/2009/03/31/1426758.html(玩转Google开源C++单元测试框架Google Test系列(gtest))

     4、转载请保留该博客地址:http://mzhx-com.iteye.com/

    

正所谓,外行看热闹,内行看门道,在此就不多做解释了,注释和源码相信应该是最好的老师吧

 

工程结构图表:

sample1.h

//一个用来展示如何应用Google C++测试框架的简单程序示例

#ifndef GTEST_SAMPLES_SAMPLE1_H_
#define GTEST_SAMPLES_SAMPLE1_H_

// Returns n! (the factorial of n).  For negative n, n! is defined to be 1.
//返回n!(n的阶乘),对于负数n,n!约定等于1
int Factorial(int n);

// Returns true iff n is a prime number.
//如果n是素数返回true
bool IsPrime(int n);

#endif  // GTEST_SAMPLES_SAMPLE1_H_

 

sample1.cc

//一个用来展示如何应用Google C++测试框架的简单程序示例
#include "stdafx.h"
#include "sample1.h"
// Returns n! (the factorial of n).  For negative n, n! is defined to be 1.
//返回n!(n的阶乘),对于负数n,n!约定等于1
int Factorial(int n) {
	int result = 1;
	for (int i = 1; i <= n; i++) {
		result *= i;
	}
	return result;
}
// Returns true iff n is a prime number.
//如果n是素数返回true
bool IsPrime(int n) {
	// Trivial case 1: small numbers
	//情况1:小于等于1的数字
	if (n <= 1) return false;
	// Trivial case 2: even numbers
	//情况2:整数
	if (n % 2 == 0) return n == 2;
	// Now, we have that n is odd and n >= 3.
	//现在,对于那些大于3的奇数
	// Try to divide n by every odd number i, starting from 3
	//从3开始,用每个奇数i去除n
	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;
}

 

sample1_unittest.cc

// This sample shows how to write a simple unit test for a function,
// using Google C++ testing framework.
//这个示例用来展示如何应用Google C++测试框架来写一个简单的函数测试单元
// Writing a unit test using Google C++ testing framework is easy as 1-2-3:
//应用Google C++写一个单元测试很简单,只需要1-2-3共三个步骤


// Step 1. Include necessary header files such that the stuff your
// test logic needs is declared.
//第一步:引入一些必须的头文件
// Don't forget gtest.h, which declares the testing framework.
//不要忘了引入声明测试框架的gtest.h头文件
#include "stdafx.h"
#include <limits.h>
#include "sample1.h"
#include <gtest/gtest.h>


// Step 2. Use the TEST macro to define your tests.
//第二步:应用TEST宏来定义你的测试

//TEST has two parameters: the test case name and the test name.
//TEST宏包含两个参数:一个案例【TestCaseName】名,一个测试【TestName】名

// 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.
//你应该使用一些宏命令去指出测试是否成功

//EXPECT_TRUE and EXPECT_EQ are  examples of such macros. 
//其中EXPECT_TRUE和EXPECT_EQ就是这样的宏的例子

// For a complete list, see gtest.h.
//要查看完整的列表,可以去看看gtest.h头文件

// <TechnicalDetails>
//
// In Google Test, tests are grouped into test cases.  
//在gtest中,测试都被分组到测试案例中

// This is how we keep test code organized. 
//这就是我们有效组织测试代码的方式

//  You should put logically related tests into the same test case.
//你应该将这些逻辑上相关的测试应用到相似的测试案例中去

// The test case name and the test name should both be valid C++ identifiers.  
//测试案例名和测试名应该都是有效的C++标识符

// And you should not use underscore (_) in the names.
//并且你不应该应用强调符号(_)到命名中

// Google Test guarantees that each test you define is run exactly
// once, but it makes no guarantee on the order the tests are
// executed.  
//gtest能够保证你定义的每个测试都能准确的运行一次,但是它并不能保证这些测试执行的顺序

//Therefore, you should write your tests in such a way
// that their results don't depend on their order.
//所以你应该依输出结果不依赖自身顺序的方式来写这些测试案例

// </TechnicalDetails>


// Tests Factorial().
//测试阶乘函数Factorial().

// Tests factorial of negative numbers.
//测试传入负数的情况下函数的运行情况

TEST(FactorialTest, Negative) {
  // This test is named "Negative", and belongs to the "FactorialTest"
  // test case.
  //这个测试本身被命名为“Negative”且从属于"FactorialTest"测试案例

  EXPECT_EQ(1, Factorial(-5));
  EXPECT_EQ(1, Factorial(-1));
  EXPECT_TRUE(Factorial(-10) > 0);

  // <TechnicalDetails>
  //<技术细节>

  // 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.  
  //EXPECT_EQ(expected, actual)除了在断言失败时会打印出期望值和相应的真实值外,其他的情况都和EXPECT_TRUE((expected) == (actual))相同

  //This is very helpful for debugging.
  //这对调试来说很有帮助

  //   Therefore in this case EXPECT_EQ is preferred.
  //因此这样说来EXPECT_EQ是很有用的

  // On the other hand, EXPECT_TRUE accepts any Boolean expression,and is thus more general.
  // 在另一方面,EXPECT_TRUE会接受任何的Boolean表达式,所以他的用法更普通一些

  //
  // </TechnicalDetails>
}

// Tests factorial of 0.
//使用数字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.
  //这个测试依赖于IsPrimeTest测试案例

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

// Step 3. Call RUN_ALL_TESTS() in main().
//第三步:在main()函数中调用 RUN_ALL_TESTS()函数

// We do this by linking in src/gtest_main.cc file, which consists of
// a main() function which calls RUN_ALL_TESTS() for us.
//在src/gtest_main.cc文件中有一个调用RUN_ALL_TESTS()函数的main()函数,我们可以引入该文件来实现第三步的要求

// This runs all the tests you've defined, prints the result, 
//在这里可以运行所有你定义的测试,打印输出结果

//and returns 0 if successful, or 1 otherwise.
//并且如果成功返回0,其他情况返回1

// Did you notice that we didn't register the tests?  
//你有没有发现我们并没有注册这些测试

//The RUN_ALL_TESTS() macro magically knows about all the tests we defined.
//这个RUN_ALL_TESTS()宏函数能神奇的知道我们定义的所有测试

//Isn't this convenient?
//这样是不是很方便呢,嘿嘿

 

sample2.h

//一个用来展示如何应用Google C++测试框架的简单程序示例

#ifndef GTEST_SAMPLES_SAMPLE2_H_
#define GTEST_SAMPLES_SAMPLE2_H_

#include <string.h>


// A simple string class.
//一个简单的string字符串相关类
class MyString {
private:
	const char * c_string_;
	const MyString& operator=(const MyString& rhs);

public:

	// Clones a 0-terminated C string, allocating memory using new.
	//克隆一个0结尾的C string字符串,用new关键字分配空间
	static const char * CloneCString(const char * c_string);

	////////////////////////////////////////////////////////////
	//
	// C'tors

	// The default c'tor constructs a NULL string.
	//为c_string_默认赋NULL值的构造函数

	MyString() : c_string_(NULL) {}

	// Constructs a MyString by cloning a 0-terminated C string.
	explicit MyString(const char * c_string) : c_string_(NULL) {
		Set(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类想定义为final类,所以析构函数没必要定义为virtual

	~MyString() { delete[] c_string_; }

	// Gets the 0-terminated C string this MyString object represents.
	//返回MyString对象的c_string_
	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.
	//为MyString对象的c_string赋值
	void Set(const char * c_string);
};


#endif  // GTEST_SAMPLES_SAMPLE2_H_

 

sample2.cc

#include "stdafx.h"
#include "sample2.h"

#include <string.h>

// Clones a 0-terminated C string, allocating memory using new.
//克隆复制一个以0结尾的C字符串,用new关键字申请空间
const char * MyString::CloneCString(const char * c_string) {
	if (c_string == NULL) return NULL;

	const size_t len = strlen(c_string);
	char * const clone = new char[ len + 1 ];
	memcpy(clone, c_string, len + 1);

	return clone;
}

// Sets the 0-terminated C string this MyString object
// represents.
//设置以0结尾的字符串用MyString实体表示
void MyString::Set(const char * c_string) {
	// Makes sure this works when c_string == c_string_
	//确保当c_string == c_string_时这个函数正常工作
	const char * const temp = MyString::CloneCString(c_string);
	delete[] c_string_;
	c_string_ = temp;
}

 

 

 

sample2_unittest.cc

// 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.
// 当然你也可以做些额外的必要的测试。
#include "stdafx.h"
#include "sample2.h"
#include <gtest/gtest.h>

// In this example, we test the MyString class (a simple string).
//在这个示例中,我们测试MyString类(一个简单的字符串)

// Tests the default c'tor.
//测试它的默认构造函数
TEST(MyString, DefaultConstructor) {
	const MyString s;

	// Asserts that s.c_string() returns NULL.
	//断言s.c_string()返回NULL

	// <TechnicalDetails>
	//技术细节

	// If we write NULL instead of
	//
	//   static_cast<const char *>(NULL)
	//
	// in this assertion, it will generate a warning on gcc 3.4. 
	//如果我们在这个断言中通过写NULL来代替static_cast<const char *>(NULL),那么将得到一个关于gcc3.4的警告

	//The reason is that EXPECT_EQ needs to know the types of its
	// arguments in order to print them when it fails.  
	//原因是:EXPECT_EQ需要知道它的参数的类型以便在测试失败时打印他们

	//Since NULL is #defined as 0, the compiler will use the formatter function for int to print it
	//因为NULL被定义为0,所以编译器会用int型的格式化函数来打印他

	//However, gcc thinks that NULL should be used as
	// a pointer, not an int, and therefore complains.
	//但是,gcc认为NULL应该被当做指针而不是int型,所以很是抱怨

	// The root of the problem is C++'s lack of distinction between the
	// integer number 0 and the null pointer constant.  
	//这个问题的的根源是C++中缺少对整数0和null指针常量的区分

	//Unfortunately, we have to live with this fact.
	//不幸的是,我们必须接受这个事实
	// </TechnicalDetails>
	EXPECT_STREQ(NULL, s.c_string());

	EXPECT_EQ(0, s.Length());
}

const char kHelloString[] = "Hello, world!";

// Tests the c'tor that accepts a C string.
//测试有一个字符串参数的构造函数
TEST(MyString, ConstructorFromCString) {
	const MyString s(kHelloString);
	EXPECT_TRUE(strcmp(s.c_string(), kHelloString) == 0);
	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_TRUE(strcmp(s2.c_string(), kHelloString) == 0);
}

// Tests the Set method.
//测试它的Set给字符串赋值的函数
TEST(MyString, Set) {
	MyString s;

	s.Set(kHelloString);
	EXPECT_TRUE(strcmp(s.c_string(), kHelloString) == 0);

	// Set should work when the input pointer is the same as the one
	// already in the MyString object.
	//Set函数应该在输入指针和已经在MyString对象中存在的指针一样的情况下也能工作
	s.Set(s.c_string());
	EXPECT_TRUE(strcmp(s.c_string(), kHelloString) == 0);

	// Can we set the MyString to NULL?
	//我们能把MyString设置成NULL吗?
	s.Set(NULL);
	EXPECT_STREQ(NULL, s.c_string());
}

 

 

 

sample3-inl.h

//一个用来展示如何应用Google C++测试框架的简单程序示例

#ifndef GTEST_SAMPLES_SAMPLE3_INL_H_
#define GTEST_SAMPLES_SAMPLE3_INL_H_

#include <stddef.h>


// Queue is a simple queue implemented as a singled-linked list.
//Queue就是一个简单的实现了单向链表功能的队列
// The element type must support copy constructor.
//这个元素类型必须支持拷贝构造函数

// E is the element type
//E是元素类型
template <typename E>  
class Queue;

// QueueNode is a node in a Queue, which consists of an element of type E and a pointer to the next node.
//队列节点就是一个在队列中的节点,他由一个元素类型E和指向下一个节点的指针组成
template <typename E>  
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.
	// 用一个给定元素值来创建一个节点,它的下一个节点指针被设置成NULL
	QueueNode(const E & element) : element_(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>  
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.
			//1、移除每一个节点
			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.
			//2、重置成员变量
			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.、
	//得到队列的第一个元素,如果队列为空则返回NULL
	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.
	//得到队列的最后一个元素,如果队列为空则返回NULL
	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.
	//移除队列的头部并且返回他,如果队列为空则返回NULL
	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 &);
};

#endif  // GTEST_SAMPLES_SAMPLE3_INL_H_

 

sample3_unittest.cc

// In this example, we use a more advanced feature of Google Test called
// test fixture.
//在这个示例中,我们将使用更多的gtest更高级的用法,他叫做“test fixture”(测试夹具)

// A test fixture is a place to hold objects and functions shared by
// all tests in a test case.  
//一个“test fixture”就是一个用来存放能够被所有的测试和测试案例共享的实例和函数的地方

//Using a test fixture avoids duplicating
// the test code necessary to initialize and cleanup those common
// objects for each test.  
//对于那些为每个测试中对初始化或善后处理共同示例所必须的代码来说,使用“test fixture”可以避免重复的复制

//It is also useful for defining sub-routines
// that your tests need to invoke a lot.
//

// <TechnicalDetails>
//
// The tests share the test fixture in the sense of code sharing, not data sharing.
//这些测试共享这个“test fixtur”,从意义上来说是共享代码,而不是共享数据

//   Each test is given its own fresh copy of the fixture.
//每个测试都被赋予一个他自己的关于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). 
//那些可以指明一个测试(EXPECT_TRUE, FAIL等)是否成功的宏命令应该知道当前的测试是什么
//(当一个gtest打印测试的结果的时候,就是在指出每个失败的结果所对应的测试)

//Technically, these macros invoke a member function of the Test class.
//从技术上来说,这些宏命令在调用Test 类的一个成员函数

//   Therefore, you cannot use them in a global function.  
// 因此,你不能再全局函数中使用它们,
//That's why you should put test sub-routines in a test fixture.
//这就是为什么你应该将测试子程序放到一个“test fixture”中
// </TechnicalDetails>
#include "stdafx.h"
#include <iostream>
#include "sample3-inl.h"
#include <gtest/gtest.h>
 using namespace  std;
 
// To use a test fixture, derive a class from testing::Test.
class QueueTestOfTest3 : 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.  
	//virtual void SetUp()会在每个测试运行前被调用

	//You should define it if you need to initialize the varaibles.
	//如果你想初始化一些变量,那么你应该定义这个函数

	// Otherwise, this can be skipped.
	//不然,你可以选择跳过这个函数不去实现
	virtual void SetUp() {
		cout<<"SetUp()do something"<<endl;
		q1_.Enqueue(1);
		q2_.Enqueue(2);
		q2_.Enqueue(3);
	}

	// virtual void TearDown() will be called after each test is run.
	//virtual void TearDown()会在每个测试完了之后被调用

	// 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().
	//一个用来测试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.
		// 创建一个新的队列queue,它的每一个元素都是位于q中的相似元素的两倍
		const Queue<int> * const new_q = q->Map(Double);

		// Verifies that the new queue has the same size as q.
		//验证这个新的队列和队列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.
//如果你有一个"test fixture",你应该用TEST_F代替TEST来定义一个测试

// Tests the default c'tor.
//测试默认构造函数
TEST_F(QueueTestOfTest3, DefaultConstructor) {
	// You can access data in the test fixture here.
	EXPECT_EQ(0, q0_.Size());
}

// Tests Dequeue().
//测试出队列
TEST_F(QueueTestOfTest3, Dequeue) {
	int * n = q0_.Dequeue();
	EXPECT_TRUE(n == NULL);

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

	n = q2_.Dequeue();
	ASSERT_TRUE(n != NULL);
	EXPECT_EQ(2, *n);
	EXPECT_EQ(1, q2_.Size());
	delete n;
}

// Tests the Queue::Map() function.
//测试Queue::Map() 函数
TEST_F(QueueTestOfTest3, Map) {
	MapTester(&q0_);
	MapTester(&q1_);
	MapTester(&q2_);
}

 

sample4.h

#ifndef GTEST_SAMPLES_SAMPLE4_H_
#define GTEST_SAMPLES_SAMPLE4_H_

// A simple monotonic counter.
//一个很简单单调的计数器
class Counter {
private:
	int counter_;

public:
	// Creates a counter that starts at 0.
	//创建一个起始值为0的计数器
	Counter() : counter_(0) {}

	// Returns the current counter value, and increments it.
	//返回当前的计数值,并且使他自增一
	int Increment();

	// Prints the current counter value to STDOUT.
	//采用标准输出打印当前的计数值
	void Print() const;
};

#endif  // GTEST_SAMPLES_SAMPLE4_H_

 

sample4.cc

#include <stdio.h>
#include "stdafx.h"
#include "sample4.h"

// 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_);
}

 

 

 

 

 

 

sample4_unittest.cc

#include "stdafx.h"
#include <gtest/gtest.h>
#include "sample4.h"

// Tests the Increment() method.
//测试计数器类的Increment()函数
TEST(Counter, Increment) {
	Counter c;

	// EXPECT_EQ() evaluates its arguments exactly once, so they can have side effects.
	// EXPECT_EQ()准确的评估他的参数一次,所以他们会有副作用

	EXPECT_EQ(0, c.Increment());
	EXPECT_EQ(1, c.Increment());
	EXPECT_EQ(2, c.Increment());
}

 

prime_tables.h

// This provides interface PrimeTable that determines whether a number is a
// prime and determines a next prime number.
//这里提供了一个接口类PrimeTable,他可以确定一个数字是否是素数并且确定下一个素数数字

//This interface is used
// in Google Test samples demonstrating use of parameterized tests.
//这个接口已经被应用于gtest用来展示参数化测试的示例中了

#ifndef GTEST_SAMPLES_PRIME_TABLES_H_
#define GTEST_SAMPLES_PRIME_TABLES_H_
//#include "stdafx.h"
#include <algorithm>

// The prime table interface.
//素数表接口
class PrimeTable {
 public:
  virtual ~PrimeTable() {}

  // Returns true iff n is a prime number.
  //返回true如果n是一个素数
  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.
  //返回比p大的所有素数中最小的那一个数,或者如果下一个素数超出表的容量时返回-1

  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.
			//n能够被除1和他自身以外的整数相除
			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.
			//标记所有的i的倍数(不包括i自身)不是素数
			for (int j = 2*i; j <= max; j += i) {
				is_prime_[j] = false;
			}
		}
	}

	const int is_prime_size_;
	bool* const is_prime_;
};

#endif  // GTEST_SAMPLES_PRIME_TABLES_H_

 

sample5_unittest.cc

// This sample teaches how to reuse a test fixture in multiple test
// cases by deriving sub-fixtures from it.
//这个示例教给大家怎么通过子fixtrues在一个多重的测试案例中重复使用一个“test fixture”

// When you define a test fixture, you specify the name of the test
// case that will use this fixture.  
//当你定义一个test fixture的时候,有要指定要用到该fixture的测试案例的名称

//Therefore, a test fixture can be used by only one test case.
//所以,一个test fixtrue只能够被咦一个测试案例使用

// Sometimes, more than one test cases may want to use the same or slightly different test fixtures
//有时候,也许更多的测试案例想使用一个相同或者只有少许差别的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.
//举例来说,你也许想确保所有针对GUI库的测试不会漏掉那些比如字体和笔刷之类的重要的系统资源

//In Google Test, you do
// this by putting the shared logic in a super (as in "super class")
// test fixture, 
//在gtest中,你想要实现这个可以通过把那些共同逻辑放入一个超级的test fixture中

//and then have each test case use a fixture derived
// from this super fixture.
//并且可以通过从超级test fixture派生来得到每个测试案例所需的fixture
#include "stdafx.h"
#include <limits.h>
#include <time.h>
#include "sample3-inl.h"
#include <gtest/gtest.h>
#include "sample1.h"

// In this sample, we want to ensure that every test finishes within ~5 seconds.
//在这个示例中,我们想保证每个测试都在5秒钟之内完成

//   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”的test fixture中

// QuickTest is intended to be the super fixture that other fixtures derive from
//QuickTest被设计成其他子fixtures可以用来派生的超级fixture

// therefore there is no test case with
// the name "QuickTest".  This is OK.
//所以,这里没有命名为“QuickTest”的测试案例,这样就可以了

// Later, we will derive multiple test fixtures from QuickTest.
//稍后我们会从QuickTest派生一些text fixtures

class QuickTest : public testing::Test {
protected:
	// Remember that SetUp() is run immediately before a test starts.
	//要记住,SetUp() 函数会在一个测试起始前立刻执行

	// 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.  
	// TearDown()会在一个测试结束后被立即调用

	//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.  
		//断言这个测试花费的时间没有超过5分钟

		//Did you know that you can use assertions in SetUp() and TearDown() as well?
		// 你是否知道我们也可以同样在SetUp()函数中使用断言呢?

		EXPECT_TRUE(end_time - start_time_ <= 5) << "The test took too long.";
	}

	// The UTC time (in seconds) when the test starts
	//当测试启动时的UTC时间(以秒计)

	time_t start_time_;
};


// We derive a fixture named IntegerFunctionTest from the QuickTest fixture.
//我们从QuickTest派生一个名叫“IntegerFunctionTest”的fixture

//   All tests using this fixture will be automatically required to be quick.
// 所有的使用这个fixture的测试都会无意识的被要求运行的很快
class IntegerFunctionTest : public QuickTest {
	// We don't need any more logic than already in the QuickTest fixture.
	//我们不需要比那些已经存在于QuickTest的更多的处理逻辑

	// Therefore the body is empty.
	//所以该类中的内容是空的
};


// Now we can write tests in the IntegerFunctionTest test case.
//现在我们可以在IntegerFunctionTest测试案例中去写一些测试

// Tests Factorial()
//测试计算阶乘的函数Factorial()

TEST_F(IntegerFunctionTest, Factorial) {
	// Tests factorial of negative numbers.
	EXPECT_EQ(1, Factorial(-5));
	EXPECT_EQ(1, Factorial(-1));
	EXPECT_TRUE(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()
//测试检测一个数是否为素数的函数IsPrime()
TEST_F(IntegerFunctionTest, IsPrime) {
	// Tests negative input.
	EXPECT_TRUE(!IsPrime(-1));
	EXPECT_TRUE(!IsPrime(-2));
	EXPECT_TRUE(!IsPrime(INT_MIN));

	// Tests some trivial cases.
	EXPECT_TRUE(!IsPrime(0));
	EXPECT_TRUE(!IsPrime(1));
	EXPECT_TRUE(IsPrime(2));
	EXPECT_TRUE(IsPrime(3));

	// Tests positive input.
	EXPECT_TRUE(!IsPrime(4));
	EXPECT_TRUE(IsPrime(5));
	EXPECT_TRUE(!IsPrime(6));
	EXPECT_TRUE(IsPrime(23));
}


// The next test case (named "QueueTest") also needs to be quick, so
// we derive another fixture from QuickTest.
//接下来的测试案例(命名为“QueueTest”)也需要快速运行,所以我们从QuickTest
//派生了另外一个fixture

// The QueueTest test fixture has some logic and shared objects in addition to what's in QuickTest already.
//QueueTest测试有一些自己的逻辑和那些已经在QuickTest存在的共享的对象

//   We define the additional
// stuff inside the body of the test fixture, as usual.
//通常我们在这个测试fixture的内部定义一些额外的东西

class QueueTest : public QuickTest {
protected:
	virtual void SetUp() {
		// First, we need to set up the super fixture (QuickTest).
		//首先,我们需要配置超级fixture(QuickTest)
		QuickTest::SetUp();

		// Second, some additional setup for this fixture.
		//第二,设置一些和这个fixture相关的额外的东西
		q1_.Enqueue(1);
		q2_.Enqueue(2);
		q2_.Enqueue(3);
	}

	// By default, TearDown() inherits the behavior of QuickTest::TearDown().
	//默认情况下,TearDown()函数会从QuickTest的TearDown()函数中继承相关的逻辑行为
	//   As we have no additional cleaning work
	// for QueueTest, we omit it here.
	//考虑到我们没有为QueueTest追加设计更多的清理工作逻辑,我们可以在这里忽略它
	// virtual void TearDown() {
	//   QuickTest::TearDown();
	// }

	Queue<int> q0_;
	Queue<int> q1_;
	Queue<int> q2_;
};


// Now, let's write tests using the QueueTest fixture.
//现在,我们使用QueueTest 来写我们的测试

// Tests the default constructor.
//测试默认构造函数

TEST_F(QueueTest, DefaultConstructor) {
	EXPECT_EQ(0, q0_.Size());
}

// Tests Dequeue().
//测试队列弹出函数Dequeue()

TEST_F(QueueTest, Dequeue) {
	int * n = q0_.Dequeue();
	EXPECT_TRUE(n == NULL);

	n = q1_.Dequeue();
	EXPECT_TRUE(n != NULL);
	EXPECT_EQ(1, *n);
	EXPECT_EQ(0, q1_.Size());
	delete n;

	n = q2_.Dequeue();
	EXPECT_TRUE(n != NULL);
	EXPECT_EQ(2, *n);
	EXPECT_EQ(1, q2_.Size());
	delete n;
}

// If necessary, you can derive further test fixtures from a derived fixture itself.
// 如果有必要你可以从已经派生了的fixture自身派生更深层次的test fixture

// For example, you can derive another fixture from QueueTest.
//举例来说,你可以从QueueTest派生另外一个fixture
//   Google Test imposes no limit on how deep the hierarchy can be.
//gtest没有对能够派生的层次的深度做限制
//   In practice, however, you probably don't want it to be too deep as to be confusing.
// 但是在实践中,你或许因为怕犯迷糊而不愿意把他的层次搞得太深

 

sample6_unittest.cc

// This sample shows how to test common properties of multiple
// implementations of the same interface (aka interface tests).
//这个示例用来展示如何去测试多个实现了相同接口(类)的共同属性(又叫做接口测试)

// The interface and its implementations are in this header.
//接口和他的几个相应实现都在这个头部中
#include "stdafx.h"
#include "prime_tables.h"
#include <gtest/gtest.h>

// 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.
//接下来我们定义一个test fixture的模版类

template <class T>
class PrimeTableTest : public testing::Test {
protected:
	// The ctor calls the factory function to create a prime table
	// implemented by T.
	//构造函数调用工厂方法通过泛型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.
//gtest 提供了两个方法可以针对不同的类型重复利用一些测试

// The first is called "typed tests". 
//第一个方法被称作类型测试(typed test)

//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. 
//想要写一个类型测试案例,首先应该使用TYPED_TEST_CASE(TestCaseName, TypeList)去声明并且制定类型参数

//As with TEST_F, TestCaseName must match the test fixture name.
//正如TEST_F一样,测试案例名字必须和test fixture的名字一致

// 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.
//接下来我们像定义TEST_F一样使用TYPED_TEST(TestCaseName, TestName)去定义一个类型测试

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. 
	//在测试体中,你可以通过TypeParam指定类型参数,通过TestFixture指定fixture

	// 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.
	//因为我们都在模版世界之中,在指明fixture类的成员的时候,C++明确要求写'this->'

	// 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.  
//就是这样,gtest 将会为在TYPED_TEST_CASE指定的类型列表中的每个类型重复一次TYPED_TEST

//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.
//那就是"type-parameterized tests"(类型参数化测试)能为你做的

// 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.
//首先,定义一个test fixture的模版类

//Here we just reuse the PrimeTableTest fixture defined earlier:
//在这里我们重复利用了已经早定义过的PrimeTableTest fixture

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).
// 参数是这个test fixture的名字,也是测试用例的名字(像平常一样)

//The _P suffix is for "parameterized" or "pattern".
//这个_P后缀是为了支持“parameterized”(参数化)或者“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.
//下一步,像你对待TEST_F一样,使用 TYPED_TEST_P(TestCaseName, TestName)来定义你的测试

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,
//通常,这个测试模式会被定义到一个a.h头文件中

//  and anyone can #include and instantiate it.  
//并且任何地方都可以通过#include来示例化他

//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.
//需要指出的是你在要写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

 

sample7_unittest.cc

// 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.
// 每个在测试案例中的测试都有一个参数,这个参数是一个指针并且指向已经实现的测试

// The interface and its implementations are in this header.
//这些接口和它的相关实现都在这个头文件中
#include "stdafx.h"
#include "prime_tables.h"
#include <gtest/gtest.h>

#if GTEST_HAS_PARAM_TEST

using ::testing::TestWithParam;
using ::testing::Values;

// As a general rule, tested objects should not be reused between tests.
//按照通常的惯例,已经被测试过的实体不应该在多个测试之间重复利用

// Also, their constructors and destructors of tested objects can have side effects
//另外测试实体的构造函数和析构函数会有副作用

//Thus you should create and destroy them for each test.
//所以你应该为每个测试创建并销毁他们

// In this sample we will define a simple factory function for PrimeTable objects. 
//在这个例子中我们将为PrimeTable实体定义一个简单的工厂方法

// We will instantiate objects in test's SetUp() method and delete them in TearDown() method.
// 我们将在测试的SetUp()方法中实例化实体并且在TearDown()中删除他们
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().
//在测试体、fixture的构造函数、 SetUp(), 和 TearDown()里,你可以通过GetParam()函数来指向测试参数

// In this case, the test parameter is a PrimeTableFactory interface pointer
//在这个案例中,这个测试参数是一个PrimeTableFactory接口的指针

// which we use in fixture's SetUp() to create and store an instance of PrimeTable.
//我们用这个指针在fixture的SetUp()函数中去创建和存储PrimeTable的一个实例

class PrimeTableTest : public TestWithParam<CreatePrimeTableFunc*> {
public:
	virtual ~PrimeTableTest() { delete table_; }
	virtual void SetUp() { table_ = (*GetParam())(); }
	virtual void TearDown() {
		delete table_;
		table_ = NULL;
	}

protected:
	PrimeTable* table_;
};

TEST_P(PrimeTableTest, 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(PrimeTableTest, 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(PrimeTableTest, 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:
//在这里,我们利用两个PrimeTable实体工程方法的列表来实例化我们的测试

INSTANTIATE_TEST_CASE_P(
						OnTheFlyAndPreCalculated,
						PrimeTableTest,
						Values(&CreateOnTheFlyPrimeTable, &CreatePreCalculatedPrimeTable<1000>));

#else

// Google Test doesn't support value-parameterized tests on some platforms and compilers, such as MSVC 7.1.
//gtest 在一些平台或编译器上并不至此值参数化测试,例如MSVC 7.1平台
//  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

 

 

 

GTest_Test.cpp测试入口函数

#include "stdafx.h"
#include <gtest/gtest.h>
#include <iostream>
using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
	std::cout << "Running main() from gtest_main.cc\n";
	//testing::AddGlobalTestEnvironment(new FooEnvironment);
	testing::InitGoogleTest(&argc, argv);
	return RUN_ALL_TESTS();
}

 

分享到:
评论
2 楼 郭广川 2012-09-07  
donghusoft 写道
你好,我是开发界的站长,对转载您的内容问题,我已经及时的做出来了处理,及时的添加了您的原文地址,给您带来的不便,敬请您的原谅!!!

嘿嘿,谢谢
1 楼 donghusoft 2012-09-07  
你好,我是开发界的站长,对转载您的内容问题,我已经及时的做出来了处理,及时的添加了您的原文地址,给您带来的不便,敬请您的原谅!!!

相关推荐

Global site tag (gtag.js) - Google Analytics