google test 学习笔记2-google test Advanced guide

Now that you have read Primer and learned how to write tests using Google Test, it’s time to learn some new tricks. This document will show you more assertions as well as how to construct complex failure messages, propagate fatal failures, reuse and speed up your test fixtures, and use various flags with your tests.
这篇教程会展现 更多类型的断言、如何去构建一个复杂的失败消息、传播失败的消息、重用fixtures并提速测试过程以及如何使用丰富的gtest flags
Advanced Guide共分为:ios

  1. More Assertions
  2. Teaching Google Test How to Print Your Values
  3. Death Tests
  4. Using Assertions in Sub-routines
  5. Logging Additional Information
  6. Sharing Resources Between Tests in the Same Test Case
  7. Global Set-Up and Tear-Down
  8. Value Parameterized Tests
  9. Typed Tests
  10. Type-Parameterized Tests
  11. Testing Private Code
  12. Catching Failures
  13. Getting the Current Test’s Name
  14. Extending Google Test by Handling Test Events
  15. Running Test Programs: Advanced Options

有的部分部分比较长,有的部分比较短。
这是Advanced Guide的第一部分:更多的断言shell

contentexpress

More Assertions

更多的断言app

This section covers some less frequently used, but still significant,
assertions.
这一部分包含了一些不经常使用的,可是依然很重要的ASSERTIONSless

Explicit Success and Failure

明确的成功or失败ide

These three assertions do not actually test a value or expression. Instead,
they generate a success or failure directly. Like the macros that actually
perform a test, you may stream a custom failure message into the them.
<font color="green"下面这三个宏,并非用来 检测一个值或是表达式,它们只是产生一个SUCCESS或者FAILURE的消息而已。你能够用它来流输出一个自定义的消息。函数

SUCCEED();

Generates a success. This does NOT make the overall test succeed. A test is considered successful only if none of its assertions fail during its execution.
SUCCEED()宏生成一个success消息,可是,它并不能代表这一条测试是成功的,只有当一个测试的全部断言都是成功的,这个测试才是成功的。测试

Note: SUCCEED() is purely documentary and currently doesn’t generate any user-visible output. However, we may add SUCCEED() messages to Google Test’s output in the future.
目前,SUCCEED()并不能产生一个用户可见的输出,咱们(the author)可能会在将来为它增长一些功能ui

FAIL(); ADD_FAILURE(); ADD_FAILURE_AT("file_path",line_number);

FAIL() generates a fatal failure, while ADD_FAILURE() and ADD_FAILURE_AT() generate a nonfatal failure. These are useful when control flow, rather than a Boolean expression, deteremines the test’s success or failure. For example, you might want to write something like:
FAIL()产生一个fatal failure,而ADD_FAILURE()ADD_FAILURE_AT()产生一个nonfatal failure。 在一些控制流程中,它们会比一些布尔表达式更有用,好比有一些分支是不能走的,见下例:this

 
 
 
 
switch(expression) { case 1: ... some checks ... case 2: ... some other checks ... default: FAIL() << "We shouldn't get here.";}

Availability: Linux, Windows, Mac.

Exception Assertions

异常断言

These are for verifying that a piece of code throws (or does not throw) an exception of the given type:
这些宏用来验证一些代码是否的,抛出了指定的异常

Fatal assertion Nonfatal assertion Verifies
ASSERT_THROW(statement, exception_type); EXPECT_THROW(statement, exception_type); statement throws an exception of the given type
ASSERT_ANY_THROW(statement); EXPECT_ANY_THROW(statement); statement throws an exception of any type
ASSERT_NO_THROW(statement); EXPECT_NO_THROW(statement); statement doesn’t throw any exception

Examples:

 
 
 
 
ASSERT_THROW(Foo(5), bar_exception);EXPECT_NO_THROW({ int n = 5; Bar(&n);});

Availability: Linux, Windows, Mac; since version 1.1.0.

Predicate Assertions for Better Error Messages

预测断言(为了更好的错误信息)

Even though Google Test has a rich set of assertions, they can never be complete, as it’s impossible (nor a good idea) to anticipate all the scenarios a user might run into. Therefore, sometimes a user has to use EXPECT_TRUE() to check a complex expression, for lack of a better macro. This has the problem of not showing you the values of the parts of the expression, making it hard to understand what went wrong. As a workaround, some users choose to construct the failure message by themselves, streaming it into EXPECT_TRUE(). However, this is awkward especially when the expression has side-effects or is expensive to evaluate.
尽管gtest提供了丰富多样的断言,但它不可能覆盖全部的用户可能须要的使用状况,有时候,用户不得不用EXPECT_TURE去检查一个比较复杂的表达式,由于没有合适的宏能够用,在这种状况下,一旦出错的话,并不能把相关的参数信息打印出来,做为一个workaround,一些用户就自已构造了一些错误信息输出。这样处理显得很尴尬很笨拙,尤为是这个复杂的表达式有side-effect或这个表达式拆分估值比较麻烦的时候

Google Test gives you three different options to solve this problem:
针对这种问题, gtest 提供了三种不一样的选择来解决

Using an Existing Boolean Function

使用一个已经存在的布尔型的函数

If you already have a function or a functor that returns bool (or a type that can be implicitly converted to bool), you can use it in a predicate assertion to get the function arguments printed for free:
若是你已经有一个返回布尔的函数(没有能够临时写一个),那么你可使用下面的函数:

Fatal assertion Nonfatal assertion Verifies
ASSERT_PRED1(pred1, val1); EXPECT_PRED1(pred1, val1); pred1(val1) returns true
ASSERT_PRED2(pred2, val1, val2); EXPECT_PRED2(pred2, val1, val2); pred2(val1, val2) returns true

In the above, predn is an n-ary predicate function or functor, where val1, val2, …, and valn are its arguments. The assertion succeeds if the predicate returns true when applied to the given arguments, and fails otherwise. When the assertion fails, it prints the value of each argument. In either case, the arguments are evaluated exactly once.
prednn,能够是0,1,2,3,4,5(所说目前只支持5个), 表示了后面有几个值,若是这个宏失败了的话,就会打印出全部的表达式的结果(val),这引发参数表达式只会被计算一次。

Here’s an example. Given

 
 
 
 
// Returns true iff m and n have no common divisors except 1.bool MutuallyPrime(int m, int n) { ... }const int a = 3;const int b = 4;const int c = 10;

the assertion EXPECT_PRED2(MutuallyPrime, a, b); will succeed, while the
assertion EXPECT_PRED2(MutuallyPrime, b, c); will fail with the message
EXPECT_PRED2(MutuallyPrime, b, c);失败后,会打印以下结果,能够看出,它会自动打印传入的参数:b,c的值。

!MutuallyPrime(b, c) is false, where
b is 4
c is 10

Notes:

  1. If you see a compiler error “no matching function to call” when using ASSERT_PRED* or EXPECT_PRED*, please see this for how to resolve it.
  2. Currently we only provide predicate assertions of arity <= 5. If you need a higher-arity assertion, let us know.

确实最大只到5
Availability: Linux, Windows, Mac

Using a Function That Returns an AssertionResult

使用返回值为 AssertionResult 类型的函数

While EXPECT_PRED*() and friends are handy for a quick job, the syntax is not satisfactory: you have to use different macros for different arities, and it feels more like Lisp than C++. The ::testing::AssertionResult class solves this problem.
虽然EXPECT_PRED*()和它的小伙伴们能快速处理多个参数的问题,可是这个语法看起来不是很优美,由于不一样的参数个数,你得调用不一样的宏,若是多于5个目前尚未办法处理,这样看起来更像是Lisp,而不是C++。 而类 ::testing::AssertionResult 能够解决这个问题

An AssertionResult object represents the result of an assertion (whether it’s a success or a failure, and an associated message). You can create an AssertionResult using one of these factory functions:
一个AssertionResult对象表明了一个断言结果(不论是SUCCESS或者是FAILURE,都有一个消息)。你可使用这些工厂方法来建立一个AssertionResult对象。

 
 
 
 
namespace testing {// Returns an AssertionResult object to indicate that an assertion has// succeeded.AssertionResult AssertionSuccess();// Returns an AssertionResult object to indicate that an assertion has// failed.AssertionResult AssertionFailure();}

You can then use the << operator to stream messages to the AssertionResult object.
经过AssertionResult对象,可使用流操做符<<来输出一些须要的信息。

To provide more readable messages in Boolean assertions (e.g. EXPECT_TRUE()), write a predicate function that returns AssertionResult instead of bool. For example, if you define IsEven() as:
在布尔断言中,为了提供更好的更丰富的错误诊断信息,能够构造一个预测函数,返回AssertionResult 代替返回bool:见下例

 
 
 
 
::testing::AssertionResult IsEven(int n) { if ((n % 2) == 0) return ::testing::AssertionSuccess(); else return ::testing::AssertionFailure() << n << " is odd";}

instead of:

 
 
 
 
bool IsEven(int n) { return (n % 2) == 0;}

the failed assertion EXPECT_TRUE(IsEven(Fib(4))) will print:

Value of: IsEven(Fib(4))
Actual: false (*3 is odd*)
Expected: true

instead of a more opaque

Value of: IsEven(Fib(4))
Actual: false
Expected: true

If you want informative messages in EXPECT_FALSE and ASSERT_FALSE
as well, and are fine with making the predicate slower in the success
case, you can supply a success message:
若是你想要更丰富的信息,一样的,你也能够在SUCCESS 的状况下输出一些本身想要的信息,见下例:

 
 
 
 
::testing::AssertionResult IsEven(int n) { if ((n % 2) == 0) return ::testing::AssertionSuccess() << n << " is even"; else return ::testing::AssertionFailure() << n << " is odd";}

Then the statement EXPECT_FALSE(IsEven(Fib(6))) will print

Value of: IsEven(Fib(6))
Actual: true (8 is even)
Expected: false

Availability: Linux, Windows, Mac; since version 1.4.1.

Using a Predicate-Formatter

使用格式化宏

If you find the default message generated by (ASSERT|EXPECT)_PRED* and (ASSERT|EXPECT)_(TRUE|FALSE) unsatisfactory, or some arguments to your predicate do not support streaming to ostream, you can instead use the following predicate-formatter assertions to fully customize how the message is formatted:
下面的这些宏,能够彻底的自定义输出消息的格式

Fatal assertion Nonfatal assertion Verifies
ASSERT_PRED_FORMAT1(pred_format1, val1); EXPECT_PRED_FORMAT1(pred_format1, val1`); pred_format1(val1) is successful
ASSERT_PRED_FORMAT2(pred_format2, val1, val2); EXPECT_PRED_FORMAT2(pred_format2, val1, val2); pred_format2(val1, val2) is successful
... ... ...

The difference between this and the previous two groups of macros is that instead of a predicate, (ASSERT|EXPECT)_PRED_FORMAT* take a predicate-formatter (pred_formatn), which is a function or functor with the signature:
这些宏和上面介绍的宏(ASSERT_PRED*)最大的不一样是多了_FORMAT*部分,这些宏通常与下面的函数一块儿使用:

::testing::AssertionResult PredicateFormattern(const char*expr1, const char*expr2, ... const char*exprn, T1val1, T2val2, ... Tnvaln);

where val1, val2, …, and valn are the values of the predicate arguments, and expr1, expr2, …, and exprn are the corresponding expressions as they appear in the source code. The types T1, T2, …, and Tn can be either value types or reference types. For example, if an argument has type Foo, you can declare it as either Foo or const Foo&, whichever is appropriate.
val1, val2, …, _valn_是运行被测试函数须要的参数,这些参数的类型能够是值类型,也能够是引用类型。 expr1, expr2,…, exprn 是对应于 val* 的字符串。

若是 val1 是引用类型,那么 expr1 应该是什么呢?它一直是字符串,能表示这个对象的哪一部分呢?仍是对象的名字?

A predicate-formatter returns a ::testing::AssertionResult object to indicate whether the assertion has succeeded or not. The only way to create such an object is to call one of these factory functions:
一个 predicate-formatter返回一个::testing::AssertionResult的对象,用来标识SUCCESS或者FAILURE。建立 predicate-formatter的惟一办法是使用这个工厂函数。

As an example, let’s improve the failure message in the previous example, which uses EXPECT_PRED2():

 
 
 
 
// Returns the smallest prime common divisor of m and n,// or 1 when m and n are mutually prime.int SmallestPrimeCommonDivisor(int m, int n) { ... }// A predicate-formatter for asserting that two integers are mutually prime.::testing::AssertionResult AssertMutuallyPrime(const char* m_expr, const char* n_expr, int m, int n) { if (MutuallyPrime(m, n)) return ::testing::AssertionSuccess(); return ::testing::AssertionFailure() << m_expr << " and " << n_expr << " (" << m << " and " << n << ") are not mutually prime, " << "as they have a common divisor " << SmallestPrimeCommonDivisor(m, n);}

With this predicate-formatter, we can use

 
 
 
 
EXPECT_PRED_FORMAT2(AssertMutuallyPrime, b, c);

to generate the message

b and c (4 and 10) are not mutually prime, as they have a common divisor 2.

As you may have realized, many of the assertions we introduced earlier are special cases of (EXPECT|ASSERT)_PRED_FORMAT*. In fact, most of them are indeed defined using (EXPECT|ASSERT)_PRED_FORMAT*.
其实前面介绍的一些简单的断言都是(EXPECT|ASSERT)_PRED_FORMAT*的特例,它们大多数的内部实现都是用的(EXPECT|ASSERT)_PRED_FORMAT*


在使用(EXPECT|ASSERT)_PRED_FORMAT*时,须要一个predicate-formatter函数来配合使用,配合方式以下:

 
 
 
 
//predicate-formatter::testing::AssertionResult XXXXXXXXXXX(const char* expr_1, const char* expr_2, ... , const char* expr_n, T1 val_1, T2 val_2, ... , Tn val_n){ //code here}//the macroEXPECT_PRED_FORMATn(XXXXXXXXXXX, val_1,val_2,..., val_n);

须要注意的是,代码中XXXXXXXXXXX部分要彻底相同,即要有相同的函数名

Availability: Linux, Windows, Mac.

Floating-Point Comparison

浮点数的比较

Comparing floating-point numbers is tricky. Due to round-off errors, it is very unlikely that two floating-points will match exactly. Therefore, ASSERT_EQ ‘s naive comparison usually doesn’t work. And since floating-points can have a wide value range, no single fixed error bound works. It’s better to compare by a fixed relative error bound, except for values close to 0 due to the loss of precision there.
浮点数存在截断偏差,两个浮点数之间通常不能精确的相等,因此之间的比较宏都不能用于浮点数的比较,并且浮点数表示的范围很大,远比一样占据4个字节的int表示的范围大,那么它的分辨率必定是很低。因此最好使用相对偏差来进行比较,除了跟0相比。

In general, for floating-point comparison to make sense, the user needs to carefully choose the error bound. If they don’t want or care to, comparing in terms of Units in the Last Place (ULPs) is a good default, and Google Test provides assertions to do this. Full details about ULPs are quite long; if you want to learn more, see this article on float comparison.
通常来讲,对于浮点数的比较,用户须要自已指定偏差范围,若是不想指定或是对这个不关心的话, 使用ULPs是一个很是好的选择,gtest也提供了相应的断言。

须要注意的是,因为浮点表示的范围很是大,以经常使用的float和int为例,他们都占据4个字节,可是float的范围很大,float是使用的二进制的科学计数法,对应到十进制来讲,只有6到7位的有效数字,若是一个float比较大时,用非科学计数法表示时,其小数位乃至个位、十位,都有多是不精确的,因此在比较时,能够考虑两数相减再与0.0f比较,状况会好一点。

Floating-Point Macros

浮点数比较的宏

Fatal assertion Nonfatal assertion Verifies
ASSERT_FLOAT_EQ(expected, actual); EXPECT_FLOAT_EQ(expected, actual); the two float values are almost equal
ASSERT_DOUBLE_EQ(expected, actual); EXPECT_DOUBLE_EQ(expected, actual); the two double values are almost equal

By “almost equal”, we mean the two values are within 4 ULP’s from each other.
对于浮点数比较下的默认相等,这两个宏指的是小于 有个 ULP’s

The following assertions allow you to choose the acceptable error bound:
下面的宏容许用户本身指定一个精度来进行比较

Fatal assertion Nonfatal assertion Verifies
ASSERT_NEAR(val1, val2, abs_error); EXPECT_NEAR(val1, val2, abs_error); the difference between val1 and val2 doesn’t exceed the given absolute error

Availability: Linux, Windows, Mac.

Floating-Point Predicate-Format Functions

浮点数的预测格式比较

Some floating-point operations are useful, but not that often used. In order to avoid an explosion of new macros, we provide them as predicate-format functions that can be used in predicate assertion macros (e.g. EXPECT_PRED_FORMAT2, etc).
虽然一些浮点数的操做颇有用,可是却不怎么经常使用,为了不定义大量的浮点数相关的宏,这里定义了 _predicate-format_宏来

 
 
 
 
EXPECT_PRED_FORMAT2(::testing::FloatLE, val1, val2);EXPECT_PRED_FORMAT2(::testing::DoubleLE, val1, val2);

Verifies that val1 is less than, or almost equal to, val2. You can replace EXPECT_PRED_FORMAT2 in the above table with ASSERT_PRED_FORMAT2.

Availability: Linux, Windows, Mac.

Windows HRESULT assertions

These assertions test for HRESULT success or failure.

Fatal assertion Nonfatal assertion Verifies
ASSERT_HRESULT_SUCCEEDED(expression); EXPECT_HRESULT_SUCCEEDED(expression); expression is a success HRESULT
ASSERT_HRESULT_FAILED(expression); EXPECT_HRESULT_FAILED(expression); expression is a failure HRESULT

The generated output contains the human-readable error message associated with the HRESULT code returned by expression.
这些宏会输出一些人类可读的错误消息

You might use them like this:

 
 
 
 
CComPtr shell;ASSERT_HRESULT_SUCCEEDED(shell.CoCreateInstance(L"Shell.Application"));CComVariant empty;ASSERT_HRESULT_SUCCEEDED(shell->ShellExecute(CComBSTR(url), empty, empty, empty, empty));

Availability: Windows.

Type Assertions

类型断言

You can call the function

 
 
 
 
::testing::StaticAssertTypeEq<T1, T2>();

to assert that types T1 and T2 are the same. The function does nothing if the assertion is satisfied. If the types are different, the function call will fail to compile, and the compiler error message will likely (depending on the compiler) show you the actual values of T1 and T2. This is mainly useful inside template code.
::testing::StaticAssertTypeEq<T1, T2>()这货用来比较T1T2两个类型是否相同,好比是否同为int。若是相同,这个函数什么也不作,若是不相同,这个函数会产生一个编译错误,错误消息会显示T1T2的真实类型(具体消息的格式及如何显示取决于编译器)。在使用模板的代码中,这个函数会比较有用。

Caveat: When used inside a member function of a class template or a function template, StaticAssertTypeEq<T1, T2>() is effective only if the function is instantiated. For example, given:

 
 
 
 
template <typename T> class Foo {public: void Bar() { ::testing::StaticAssertTypeEq<int, T>(); }};

the code:

 
 
 
 
void Test1() { Foo<bool> foo; }

will not generate a compiler error, as Foo<bool>::Bar() is never
actually instantiated. Instead, you need:

 
 
 
 
void Test2() { Foo<bool> foo; foo.Bar(); }

to cause a compiler error.

注意: 想要用这个函数来检测模板函数中类型是否匹配或相同,必须保证使用这个函数的代码会被执行到,不然这个函数是不会起做用的。详见上例。

Availability: Linux, Windows, Mac; since version 1.3.0.

Assertion Placement

断言位置

You can use assertions in any C++ function. In particular, it doesn’t have to be a method of the test fixture class. The one constraint is that assertions that generate a fatal failure (FAIL* and ASSERT_*) can only be used in void-returning functions. This is a consequence of Google Test not using exceptions. By placing it in a non-void function you’ll get a confusing compile error like "error: void value not ignored as it ought to be".
能够在代码的任何位置处使用断言,除了产生fatal error 的ASSERT_*等,他们只能在返回值为void的函数内使用。这是由于gtest没有使用异常,若是把它们放在了返回值不为void的函数体内,可能会产生一个编译错相似于:"error: void value not ignored as it ought to be"

If you need to use assertions in a function that returns non-void, one option is to make the function return the value in an out parameter instead. For example, you can rewrite T2 Foo(T1 x) to void Foo(T1 x, T2* result). You need to make sure that *result contains some sensible value even when the function returns prematurely. As the function now returns void, you can use any assertion inside of it.
若是非要返回值不为void的函数内使用这些fatal error的ASSERTION,能够考虑将其返回值封闭成输出参数 r i g h t a r r o w 使用引用或指针

If changing the function’s type is not an option, you should just use assertions that generate non-fatal failures, such as ADD_FAILURE* and EXPECT_*.
若是不考虑上面将返回值封闭成参数的状况,那么就只能用non-fatal ASSERTIONS了

Note: Constructors and destructors are not considered void-returning functions, according to the C++ language specification, and so you may not use fatal assertions in them. You’ll get a compilation error if you try. A simple workaround is to transfer the entire body of the constructor or destructor to a private void-returning method. However, you should be aware that a fatal assertion failure in a constructor does not terminate the current test, as your intuition might suggest; it merely returns from the constructor early, possibly leaving your object in a partially-constructed state. Likewise, a fatal assertion failure in a destructor may leave your object in a partially-destructed state. Use assertions carefully in these situations!
注意,构造函数和析构函数并非返回值为void的函数。因此它们也不能用fatal error的assertion,不过能够考虑将他们的函数体拎出来 ,放到一个返回值为void的函数内,这样就可使用fatal error的assertion了。不过须要注意的是,若是在这些fatal assertion断言失败的话,只会提早退出构造/析构函数,并不会终止程序运算,这样能够会使你的对象处于一个部分构造/析构的状态,因此,在构造/析构函数中使用fatal assertion要很是当心。



相关文章
相关标签/搜索