gtest简介及简单使用

分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow

也欢迎大家转载本篇文章。分享知识,造福人民,实现我们中华民族伟大复兴!

               

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

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

 

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

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

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

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

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

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

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

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

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

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

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


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

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

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

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

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

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

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


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


下面是对gtest的一些总结:

1.  TEST(test_case_name, test_name)

TEST_F(test_fixture,test_name)

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


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

1. 新建一个gtestSamples的工程;

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

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

4. fun.h文件内容为:

#ifndef _FUN_H_#define _FUN_H_#include <string.h>#include <algorithm>// Returns n! (the factorial of n).  For negative n, n! is defined to be 1.int Factorial(int n);// Returns true if n is a prime number.bool IsPrime(int n);// A simple string class.class MyString {privateconst 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 typeclass 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 typeclass 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 {privateint 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 {publicvirtual ~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 {publicvirtual 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; }privatevoid 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 = 1for (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 NULLconst 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() constprintf("%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 {protectedvirtual void SetUp() {  // First, we need to set up the super fixture (QuickTest).  QuickTest::SetUp();  // Second, some additional setup for this fixture.  q1_.Enqueue(1);  q2_.Enqueue(2);  q2_.Enqueue(3); } // By default, TearDown() inherits the behavior of // QuickTest::TearDown().  As we have no additional cleaning work // for QueueTest, we omit it here. // // virtual void TearDown() { //   QuickTest::TearDown(); // } Queue<int> q0_; Queue<int> q1_; Queue<int> q2_;};// Now, let's write tests using the QueueTest fixture.// Tests the default constructor.TEST_F(QueueTest1, DefaultConstructor) { EXPECT_EQ(0u, q0_.Size());}// Tests Dequeue().TEST_F(QueueTest1, Dequeue) { int* n = q0_.Dequeue(); EXPECT_TRUE(n == NULL); n = q1_.Dequeue(); EXPECT_TRUE(n != NULL); EXPECT_EQ(1, *n); EXPECT_EQ(0u, q1_.Size()); delete n; n = q2_.Dequeue(); EXPECT_TRUE(n != NULL); EXPECT_EQ(2, *n); EXPECT_EQ(1u, q2_.Size()); delete n;}/*-------------------TYPED_TEST macro and TYPED_TEST_P macro------------------*///Sample 6: This sample shows how to test common properties of multiple// implementations of the same interface (aka interface tests).// First, we define some factory functions for creating instances of// the implementations.  You may be able to skip this step if all your// implementations can be constructed the same way.template <class T>PrimeTable* CreatePrimeTable();template <>PrimeTable* CreatePrimeTable<OnTheFlyPrimeTable>() { return new OnTheFlyPrimeTable;}template <>PrimeTable* CreatePrimeTable<PreCalculatedPrimeTable>() { return new PreCalculatedPrimeTable(10000);}// Then we define a test fixture class template.template <class T>class PrimeTableTest : public testing::Test {protected// The ctor calls the factory function to create a prime table // implemented by T. PrimeTableTest() : table_(CreatePrimeTable<T>()) {} virtual ~PrimeTableTest() { delete table_; } // Note that we test an implementation via the base interface // instead of the actual implementation class.  This is important // for keeping the tests close to the real world scenario, where the // implementation is invoked via the base interface.  It avoids // got-yas where the implementation class has a method that shadows // a method with the same name (but slightly different argument // types) in the base interface, for example. PrimeTable* const table_;};#if GTEST_HAS_TYPED_TESTusing testing::Types;// Google Test offers two ways for reusing tests for different types.// The first is called "typed tests".  You should use it if you// already know *all* the types you are gonna exercise when you write// the tests.// To write a typed test case, first use////   TYPED_TEST_CASE(TestCaseName, TypeList);//// to declare it and specify the type parameters.  As with TEST_F,// TestCaseName must match the test fixture name.// The list of types we want to test.typedef Types<OnTheFlyPrimeTable, PreCalculatedPrimeTable> Implementations;TYPED_TEST_CASE(PrimeTableTest, Implementations);// Then use TYPED_TEST(TestCaseName, TestName) to define a typed test,// similar to TEST_F.TYPED_TEST(PrimeTableTest, ReturnsFalseForNonPrimes) { // Inside the test body, you can refer to the type parameter by // TypeParam, and refer to the fixture class by TestFixture.  We // don't need them in this example. // Since we are in the template world, C++ requires explicitly // writing 'this->' when referring to members of the fixture class. // This is something you have to learn to live with. EXPECT_FALSE(this->table_->IsPrime(-5)); EXPECT_FALSE(this->table_->IsPrime(0)); EXPECT_FALSE(this->table_->IsPrime(1)); EXPECT_FALSE(this->table_->IsPrime(4)); EXPECT_FALSE(this->table_->IsPrime(6)); EXPECT_FALSE(this->table_->IsPrime(100));}TYPED_TEST(PrimeTableTest, ReturnsTrueForPrimes) { EXPECT_TRUE(this->table_->IsPrime(2)); EXPECT_TRUE(this->table_->IsPrime(3)); EXPECT_TRUE(this->table_->IsPrime(5)); EXPECT_TRUE(this->table_->IsPrime(7)); EXPECT_TRUE(this->table_->IsPrime(11)); EXPECT_TRUE(this->table_->IsPrime(131));}TYPED_TEST(PrimeTableTest, CanGetNextPrime) { EXPECT_EQ(2, this->table_->GetNextPrime(0)); EXPECT_EQ(3, this->table_->GetNextPrime(2)); EXPECT_EQ(5, this->table_->GetNextPrime(3)); EXPECT_EQ(7, this->table_->GetNextPrime(5)); EXPECT_EQ(11, this->table_->GetNextPrime(7)); EXPECT_EQ(131, this->table_->GetNextPrime(128));}// That's it!  Google Test will repeat each TYPED_TEST for each type// in the type list specified in TYPED_TEST_CASE.  Sit back and be// happy that you don't have to define them multiple times.#endif  // GTEST_HAS_TYPED_TEST#if GTEST_HAS_TYPED_TEST_Pusing testing::Types;// Sometimes, however, you don't yet know all the types that you want// to test when you write the tests.  For example, if you are the// author of an interface and expect other people to implement it, you// might want to write a set of tests to make sure each implementation// conforms to some basic requirements, but you don't know what// implementations will be written in the future.//// How can you write the tests without committing to the type// parameters?  That's what "type-parameterized tests" can do for you.// It is a bit more involved than typed tests, but in return you get a// test pattern that can be reused in many contexts, which is a big// win.  Here's how you do it:// First, define a test fixture class template.  Here we just reuse// the PrimeTableTest fixture defined earlier:template <class T>class PrimeTableTest2 : public PrimeTableTest<T> {};// Then, declare the test case.  The argument is the name of the test// fixture, and also the name of the test case (as usual).  The _P// suffix is for "parameterized" or "pattern".TYPED_TEST_CASE_P(PrimeTableTest2);// Next, use TYPED_TEST_P(TestCaseName, TestName) to define a test,// similar to what you do with TEST_F.TYPED_TEST_P(PrimeTableTest2, ReturnsFalseForNonPrimes) { EXPECT_FALSE(this->table_->IsPrime(-5)); EXPECT_FALSE(this->table_->IsPrime(0)); EXPECT_FALSE(this->table_->IsPrime(1)); EXPECT_FALSE(this->table_->IsPrime(4)); EXPECT_FALSE(this->table_->IsPrime(6)); EXPECT_FALSE(this->table_->IsPrime(100));}TYPED_TEST_P(PrimeTableTest2, ReturnsTrueForPrimes) { EXPECT_TRUE(this->table_->IsPrime(2)); EXPECT_TRUE(this->table_->IsPrime(3)); EXPECT_TRUE(this->table_->IsPrime(5)); EXPECT_TRUE(this->table_->IsPrime(7)); EXPECT_TRUE(this->table_->IsPrime(11)); EXPECT_TRUE(this->table_->IsPrime(131));}TYPED_TEST_P(PrimeTableTest2, CanGetNextPrime) { EXPECT_EQ(2, this->table_->GetNextPrime(0)); EXPECT_EQ(3, this->table_->GetNextPrime(2)); EXPECT_EQ(5, this->table_->GetNextPrime(3)); EXPECT_EQ(7, this->table_->GetNextPrime(5)); EXPECT_EQ(11, this->table_->GetNextPrime(7)); EXPECT_EQ(131, this->table_->GetNextPrime(128));}// Type-parameterized tests involve one extra step: you have to// enumerate the tests you defined:REGISTER_TYPED_TEST_CASE_P( PrimeTableTest2,  // The first argument is the test case name. // The rest of the arguments are the test names. ReturnsFalseForNonPrimes, ReturnsTrueForPrimes, CanGetNextPrime);// At this point the test pattern is done.  However, you don't have// any real test yet as you haven't said which types you want to run// the tests with.// To turn the abstract test pattern into real tests, you instantiate// it with a list of types.  Usually the test pattern will be defined// in a .h file, and anyone can #include and instantiate it.  You can// even instantiate it more than once in the same program.  To tell// different instances apart, you give each of them a name, which will// become part of the test case name and can be used in test filters.// The list of types we want to test.  Note that it doesn't have to be// defined at the time we write the TYPED_TEST_P()s.typedef Types<OnTheFlyPrimeTable, PreCalculatedPrimeTable> PrimeTableImplementations;INSTANTIATE_TYPED_TEST_CASE_P(OnTheFlyAndPreCalculated,    // Instance 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_TESTusing ::testing::TestWithParam;using ::testing::Values;// As a general rule, to prevent a test from affecting the tests that come// after it, you should create and destroy the tested objects for each test// instead of reusing them.  In this sample we will define a simple factory// function for PrimeTable objects.  We will instantiate objects in test's// SetUp() method and delete them in TearDown() method.typedef PrimeTable* CreatePrimeTableFunc();PrimeTable* CreateOnTheFlyPrimeTable() return new OnTheFlyPrimeTable();}template <size_t max_precalculated>PrimeTable* CreatePreCalculatedPrimeTable() return new PreCalculatedPrimeTable(max_precalculated);}// Inside the test body, fixture constructor, SetUp(), and TearDown() you// can refer to the test parameter by GetParam().  In this case, the test// parameter is a factory function which we call in fixture's SetUp() to// create and store an instance of PrimeTable.class PrimeTableTest1 : public TestWithParam<CreatePrimeTableFunc*> {publicvirtual ~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> > {protectedvirtual void SetUp() {  // This can be written as  //  // bool force_on_the_fly;  // int max_precalculated;  // tie(force_on_the_fly, max_precalculated) = GetParam();  //  // once the Google C++ Style Guide allows use of ::std::tr1::tie.  //  bool force_on_the_fly = ::std::tr1::get<0>(GetParam());  int max_precalculated = ::std::tr1::get<1>(GetParam());  table_ = new HybridPrimeTable(force_on_the_fly, max_precalculated); } virtual void TearDown() {  delete table_;  table_ = NULL; } HybridPrimeTable* table_;};TEST_P(PrimeTableTest3, ReturnsFalseForNonPrimes) { // Inside the test body, you can refer to the test parameter by GetParam(). // In this case, the test parameter is a PrimeTable interface pointer which // we can use directly. // Please note that you can also save it in the fixture's SetUp() method // or constructor and use saved copy in the tests. EXPECT_FALSE(table_->IsPrime(-5)); EXPECT_FALSE(table_->IsPrime(0)); EXPECT_FALSE(table_->IsPrime(1)); EXPECT_FALSE(table_->IsPrime(4)); EXPECT_FALSE(table_->IsPrime(6)); EXPECT_FALSE(table_->IsPrime(100));}TEST_P(PrimeTableTest3, ReturnsTrueForPrimes) { EXPECT_TRUE(table_->IsPrime(2)); EXPECT_TRUE(table_->IsPrime(3)); EXPECT_TRUE(table_->IsPrime(5)); EXPECT_TRUE(table_->IsPrime(7)); EXPECT_TRUE(table_->IsPrime(11)); EXPECT_TRUE(table_->IsPrime(131));}TEST_P(PrimeTableTest3, CanGetNextPrime) { EXPECT_EQ(2, table_->GetNextPrime(0)); EXPECT_EQ(3, table_->GetNextPrime(2)); EXPECT_EQ(5, table_->GetNextPrime(3)); EXPECT_EQ(7, table_->GetNextPrime(5)); EXPECT_EQ(11, table_->GetNextPrime(7)); EXPECT_EQ(131, table_->GetNextPrime(128));}// In order to run value-parameterized tests, you need to instantiate them,// or bind them to a list of values which will be used as test parameters.// You can instantiate them in a different translation module, or even// instantiate them several times.//// Here, we instantiate our tests with a list of parameters. We must combine// all variations of the boolean flag suppressing PrecalcPrimeTable and some// meaningful values for tests. We choose a small value (1), and a value that// will put some of the tested numbers beyond the capability of the// PrecalcPrimeTable instance and some inside it (10). Combine will produce all// possible combinations.INSTANTIATE_TEST_CASE_P(MeaningfulTestParameters, PrimeTableTest3, Combine(Bool(), Values(1, 10)));#else// Google Test may not support Combine() with some compilers. If we// use conditional compilation to compile out all code referring to// the gtest_main library, MSVC linker will not link that library at// all and consequently complain about missing entry point defined in// that library (fatal error LNK1561: entry point must be// defined). This dummy test keeps gtest_main linked in.TEST(DummyTest, CombineIsNotSupportedOnThisPlatform) {}#endif  // GTEST_HAS_COMBINEint main (int argc, char* argv[]){ testing::InitGoogleTest(&argc, argv); //::testing::GTEST_FLAG(filter) = "IsPrimeTest.*:FactorialTest.*"; return RUN_ALL_TESTS(); return 0;}#endif #if defined BRANCH_2// Sample 9: This sample shows how to use Google Test listener API to implement// an alternative console output and how to use the UnitTest reflection API// to enumerate test cases and tests and to inspect their results.using ::testing::EmptyTestEventListener;using ::testing::InitGoogleTest;using ::testing::Test;using ::testing::TestCase;using ::testing::TestEventListeners;using ::testing::TestInfo;using ::testing::TestPartResult;using ::testing::UnitTest;namespace// Provides alternative output mode which produces minimal amount of // information about tests. class TersePrinter : public EmptyTestEventListener { private:  // Called before any test activity starts.  virtual void OnTestProgramStart(const UnitTest& /* unit_test */) {}  // Called after all test activities have ended.  virtual void OnTestProgramEnd(const UnitTest& unit_test) {   fprintf(stdout, "TEST %s\n", unit_test.Passed() ? "PASSED" : "FAILED");   fflush(stdout);  }  // Called before a test starts.  virtual void OnTestStart(const TestInfo& test_info) {   fprintf(stdout,    "*** Test %s.%s starting.\n",    test_info.test_case_name(),    test_info.name());   fflush(stdout);  }  // Called after a failed assertion or a SUCCEED() invocation.  virtual void OnTestPartResult(const TestPartResult& test_part_result) {   fprintf(stdout,    "%s in %s:%d\n%s\n",    test_part_result.failed() ? "*** Failure" : "Success",    test_part_result.file_name(),    test_part_result.line_number(),    test_part_result.summary());   fflush(stdout);  }  // Called after a test ends.  virtual void OnTestEnd(const TestInfo& test_info) {   fprintf(stdout,    "*** Test %s.%s ending.\n",    test_info.test_case_name(),    test_info.name());   fflush(stdout);  } };  // class 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"; }}  // namespaceint main(int argc, ch

给我老师的人工智能教程打call!http://blog.csdn.net/jiangjunshow
这里写图片描述
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值