断言参考
此页面列出了 GoogleTest 提供的用于验证代码行为的断言宏。要使用它们,请添加 #include <gtest/gtest.h>
。
下面列出的大多数宏都成对出现,包括 EXPECT_
变体和 ASSERT_
变体。失败时,EXPECT_
宏会生成非致命性失败,并允许当前函数继续运行,而 ASSERT_
宏会生成致命性失败,并中止当前函数。
所有断言宏都支持使用 <<
运算符将自定义失败消息流式传输到其中,例如
EXPECT_TRUE(my_condition) << "My condition is not true";
可以流式传输到 ostream
的任何内容都可以流式传输到断言宏,特别是 C 字符串和字符串对象。如果将宽字符串(wchar_t*
、Windows 上 UNICODE
模式下的 TCHAR*
或 std::wstring
)流式传输到断言,则在打印时会将其转换为 UTF-8。
显式成功和失败
本节中的断言直接生成成功或失败,而不是测试值或表达式。当控制流(而非布尔表达式)决定测试的成功或失败时,这些断言非常有用,如下面的示例所示
switch(expression) {
case 1:
... some checks ...
case 2:
... some other checks ...
default:
FAIL() << "We shouldn't get here.";
}
SUCCEED
SUCCEED()
生成成功。这不会使整个测试成功。仅当测试的执行期间没有断言失败时,才认为测试成功。
SUCCEED
断言纯粹是文档性的,目前不会生成任何用户可见的输出。但是,我们将来可能会将 SUCCEED
消息添加到 GoogleTest 输出中。
FAIL
FAIL()
生成致命性失败,该失败会从当前函数返回。
只能在返回 void
的函数中使用。有关更多信息,请参见断言位置。
ADD_FAILURE
ADD_FAILURE()
生成非致命性失败,这允许当前函数继续运行。
ADD_FAILURE_AT
ADD_FAILURE_AT(
file_path
,
line_number
)
在指定的文件和行号处生成非致命性失败。
广义断言
以下断言允许使用匹配器来验证值。
EXPECT_THAT
EXPECT_THAT(
value
,
matcher
)
ASSERT_THAT(
value
,
matcher
)
验证 value
是否与匹配器 matcher
匹配。
例如,以下代码验证字符串 value1
是否以 "Hello"
开头,value2
是否与正则表达式匹配,以及 value3
是否介于 5 到 10 之间
#include <gmock/gmock.h>
using ::testing::AllOf;
using ::testing::Gt;
using ::testing::Lt;
using ::testing::MatchesRegex;
using ::testing::StartsWith;
...
EXPECT_THAT(value1, StartsWith("Hello"));
EXPECT_THAT(value2, MatchesRegex("Line \\d+"));
ASSERT_THAT(value3, AllOf(Gt(5), Lt(10)));
匹配器使这种形式的断言能够像英语一样读取,并生成信息丰富的失败消息。例如,如果上述对 value1
的断言失败,则生成的消息将类似于以下内容
Value of: value1
Actual: "Hi, world!"
Expected: starts with "Hello"
GoogleTest 提供了一个内置的匹配器库——参见匹配器参考。也可以编写自己的匹配器——参见快速编写新匹配器。匹配器的使用使 EXPECT_THAT
成为一个强大且可扩展的断言。
此断言的想法借鉴了 Joe Walnes 的 Hamcrest 项目,该项目将 assertThat()
添加到 JUnit。
布尔条件
以下断言测试布尔条件。
EXPECT_TRUE
EXPECT_TRUE(
condition
)
ASSERT_TRUE(
condition
)
验证 condition
是否为 true。
EXPECT_FALSE
EXPECT_FALSE(
condition
)
ASSERT_FALSE(
condition
)
验证 condition
是否为 false。
二元比较
以下断言比较两个值。值参数必须可以通过断言的比较运算符进行比较,否则会导致编译器错误。
如果参数支持 <<
运算符,则会在断言失败时调用它来打印该参数。否则,GoogleTest 将尝试以最佳方式打印它们——请参见教 GoogleTest 如何打印您的值。
参数总是只计算一次,因此参数具有副作用是可以的。但是,参数计算顺序未定义,程序不应依赖于任何特定的参数计算顺序。
这些断言适用于窄字符串和宽字符串对象(string
和 wstring
)。
另请参见浮点数比较断言,以比较浮点数并避免舍入引起的问题。
EXPECT_EQ
EXPECT_EQ(
val1
,
val2
)
ASSERT_EQ(
val1
,
val2
)
验证 val1
==
val2
。
对指针执行指针相等性比较。如果用于两个 C 字符串,它会测试它们是否在同一内存位置,而不是它们是否具有相同的值。使用EXPECT_STREQ
按值比较 C 字符串(例如 const char*
)。
将指针与 NULL
进行比较时,请使用 EXPECT_EQ(
ptr
, nullptr)
而不是 EXPECT_EQ(
ptr
, NULL)
。
EXPECT_NE
EXPECT_NE(
val1
,
val2
)
ASSERT_NE(
val1
,
val2
)
验证 val1
!=
val2
。
对指针执行指针相等性比较。如果用于两个 C 字符串,它会测试它们是否在不同的内存位置,而不是它们是否具有不同的值。使用EXPECT_STRNE
按值比较 C 字符串(例如 const char*
)。
将指针与 NULL
进行比较时,请使用 EXPECT_NE(
ptr
, nullptr)
而不是 EXPECT_NE(
ptr
, NULL)
。
EXPECT_LT
EXPECT_LT(
val1
,
val2
)
ASSERT_LT(
val1
,
val2
)
验证 val1
<
val2
。
EXPECT_LE
EXPECT_LE(
val1
,
val2
)
ASSERT_LE(
val1
,
val2
)
验证 val1
<=
val2
。
EXPECT_GT
EXPECT_GT(
val1
,
val2
)
ASSERT_GT(
val1
,
val2
)
验证 val1
>
val2
.
EXPECT_GE
EXPECT_GE(
val1
,
val2
)
ASSERT_GE(
val1
,
val2
)
验证 val1
>=
val2
.
字符串比较
以下断言比较两个 C 字符串。要比较两个 string
对象,请改用 EXPECT_EQ
或 EXPECT_NE
。
这些断言也接受宽 C 字符串 (wchar_t*
)。如果两个宽字符串的比较失败,它们的值将以 UTF-8 窄字符串的形式打印。
要将 C 字符串与 NULL
进行比较,请使用 EXPECT_EQ(
c_string
, nullptr)
或 EXPECT_NE(
c_string
, nullptr)
。
EXPECT_STREQ
EXPECT_STREQ(
str1
,
str2
)
ASSERT_STREQ(
str1
,
str2
)
验证两个 C 字符串 str1
和 str2
具有相同的内容。
EXPECT_STRNE
EXPECT_STRNE(
str1
,
str2
)
ASSERT_STRNE(
str1
,
str2
)
验证两个 C 字符串 str1
和 str2
具有不同的内容。
EXPECT_STRCASEEQ
EXPECT_STRCASEEQ(
str1
,
str2
)
ASSERT_STRCASEEQ(
str1
,
str2
)
验证两个 C 字符串 str1
和 str2
具有相同的内容,忽略大小写。
EXPECT_STRCASENE
EXPECT_STRCASENE(
str1
,
str2
)
ASSERT_STRCASENE(
str1
,
str2
)
验证两个 C 字符串 str1
和 str2
具有不同的内容,忽略大小写。
浮点数比较
以下断言比较两个浮点数值。
由于舍入误差,两个浮点数值完全匹配的可能性很小,因此 EXPECT_EQ
不适用。通常,为了使浮点数比较有意义,用户需要仔细选择误差范围。
GoogleTest 还提供了使用基于最后一位单位 (ULP) 的默认误差范围的断言。要了解有关 ULP 的更多信息,请参阅文章比较浮点数。
EXPECT_FLOAT_EQ
EXPECT_FLOAT_EQ(
val1
,
val2
)
ASSERT_FLOAT_EQ(
val1
,
val2
)
验证两个 float
值 val1
和 val2
近似相等,彼此相差在 4 个 ULP 之内。 无穷大和最大的有限浮点值被认为相隔一个 ULP。
EXPECT_DOUBLE_EQ
EXPECT_DOUBLE_EQ(
val1
,
val2
)
ASSERT_DOUBLE_EQ(
val1
,
val2
)
验证两个 double
值 val1
和 val2
近似相等,彼此相差在 4 个 ULP 之内。 无穷大和最大的有限双精度浮点值被认为相隔一个 ULP。
EXPECT_NEAR
EXPECT_NEAR(
val1
,
val2
,
abs_error
)
ASSERT_NEAR(
val1
,
val2
,
abs_error
)
验证 val1
和 val2
之间的差异不超过绝对误差范围 abs_error
。
如果 val
和 val2
都是相同符号的无穷大,则认为差异为 0。 否则,如果任一值为无穷大,则认为差异为无穷大。 所有非 NaN 值(包括无穷大)都被认为不超过无穷大的 abs_error
。
异常断言
以下断言验证一段代码是否抛出异常或不抛出异常。 使用需要启用构建环境中的异常。
请注意,被测试的代码段可以是复合语句,例如
EXPECT_NO_THROW({
int n = 5;
DoSomething(&n);
});
EXPECT_THROW
EXPECT_THROW(
statement
,
exception_type
)
ASSERT_THROW(
statement
,
exception_type
)
验证 statement
抛出 exception_type
类型的异常。
EXPECT_ANY_THROW
EXPECT_ANY_THROW(
statement
)
ASSERT_ANY_THROW(
statement
)
验证 statement
抛出任何类型的异常。
EXPECT_NO_THROW
EXPECT_NO_THROW(
statement
)
ASSERT_NO_THROW(
statement
)
验证 statement
不抛出任何异常。
谓词断言
以下断言允许验证更复杂的谓词,同时打印比单独使用 EXPECT_TRUE
更清晰的失败消息。
EXPECT_PRED*
EXPECT_PRED1(
pred
,
val1
)
EXPECT_PRED2(
pred
,
val1
,
val2
)
EXPECT_PRED3(
pred
,
val1
,
val2
,
val3
)
EXPECT_PRED4(
pred
,
val1
,
val2
,
val3
,
val4
)
EXPECT_PRED5(
pred
,
val1
,
val2
,
val3
,
val4
,
val5
)
ASSERT_PRED1(
pred
,
val1
)
ASSERT_PRED2(
pred
,
val1
,
val2
)
ASSERT_PRED3(
pred
,
val1
,
val2
,
val3
)
ASSERT_PRED4(
pred
,
val1
,
val2
,
val3
,
val4
)
ASSERT_PRED5(
pred
,
val1
,
val2
,
val3
,
val4
,
val5
)
验证当传递给定的值作为参数时,谓词pred
返回true
。
参数pred
是一个函数或函数对象,它接受与对应宏接受的值一样多的参数。如果pred
对给定的参数返回true
,则断言成功,否则断言失败。
当断言失败时,它会打印每个参数的值。参数总是只计算一次。
例如,请参阅以下代码
// Returns true if 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;
...
EXPECT_PRED2(MutuallyPrime, a, b); // Succeeds
EXPECT_PRED2(MutuallyPrime, b, c); // Fails
在上面的例子中,第一个断言成功,第二个断言失败,并显示以下消息
MutuallyPrime(b, c) is false, where
b is 4
c is 10
请注意,如果给定的谓词是一个重载函数或函数模板,则断言宏可能无法确定要使用哪个版本,并且可能需要显式指定函数的类型。例如,对于一个布尔函数IsPositive()
,它被重载为接受单个int
或double
参数,则需要编写以下内容之一
EXPECT_PRED1(static_cast<bool (*)(int)>(IsPositive), 5);
EXPECT_PRED1(static_cast<bool (*)(double)>(IsPositive), 3.14);
简单地编写EXPECT_PRED1(IsPositive, 5);
将导致编译器错误。类似地,要使用模板函数,请指定模板参数
template <typename T>
bool IsNegative(T x) {
return x < 0;
}
...
EXPECT_PRED1(IsNegative<int>, -5); // Must specify type for IsNegative
如果模板有多个参数,请将谓词括在括号中,以便正确解析宏参数
ASSERT_PRED2((MyPredicate<int, int>), 5, 0);
EXPECT_PRED_FORMAT*
EXPECT_PRED_FORMAT1(
pred_formatter
,
val1
)
EXPECT_PRED_FORMAT2(
pred_formatter
,
val1
,
val2
)
EXPECT_PRED_FORMAT3(
pred_formatter
,
val1
,
val2
,
val3
)
EXPECT_PRED_FORMAT4(
pred_formatter
,
val1
,
val2
,
val3
,
val4
)
EXPECT_PRED_FORMAT5(
pred_formatter
,
val1
,
val2
,
val3
,
val4
,
val5
)
ASSERT_PRED_FORMAT1(
pred_formatter
,
val1
)
ASSERT_PRED_FORMAT2(
pred_formatter
,
val1
,
val2
)
ASSERT_PRED_FORMAT3(
pred_formatter
,
val1
,
val2
,
val3
)
ASSERT_PRED_FORMAT4(
pred_formatter
,
val1
,
val2
,
val3
,
val4
)
ASSERT_PRED_FORMAT5(
pred_formatter
,
val1
,
val2
,
val3
,
val4
,
val5
)
验证当传递给定的值作为参数时,谓词pred_formatter
成功。
参数pred_formatter
是一个谓词格式化器,它是一个具有以下签名的函数或函数对象
testing::AssertionResult PredicateFormatter(const char* expr1,
const char* expr2,
...
const char* exprn,
T1 val1,
T2 val2,
...
Tn valn);
其中val1
, val2
, …, valn
是谓词参数的值,expr1
, expr2
, …, exprn
是它们在源代码中出现的相应表达式。类型T1
, T2
, …, Tn
可以是值类型或引用类型;如果参数的类型为T
,则可以将其声明为T
或const T&
,以适用者为准。有关返回类型testing::AssertionResult
的更多信息,请参见使用返回AssertionResult的函数。
例如,请参阅以下代码
// 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) { ... }
// Returns true if m and n have no common divisors except 1.
bool MutuallyPrime(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);
}
...
const int a = 3;
const int b = 4;
const int c = 10;
...
EXPECT_PRED_FORMAT2(AssertMutuallyPrime, a, b); // Succeeds
EXPECT_PRED_FORMAT2(AssertMutuallyPrime, b, c); // Fails
在上面的例子中,最后的断言失败,谓词格式化器产生以下失败消息
b and c (4 and 10) are not mutually prime, as they have a common divisor 2
Windows HRESULT 断言
以下断言测试HRESULT
的成功或失败。例如
CComPtr<IShellDispatch2> shell;
ASSERT_HRESULT_SUCCEEDED(shell.CoCreateInstance(L"Shell.Application"));
CComVariant empty;
ASSERT_HRESULT_SUCCEEDED(shell->ShellExecute(CComBSTR(url), empty, empty, empty, empty));
生成的输出包含与返回的HRESULT
代码关联的人类可读错误消息。
EXPECT_HRESULT_SUCCEEDED
EXPECT_HRESULT_SUCCEEDED(
expression
)
ASSERT_HRESULT_SUCCEEDED(
expression
)
验证expression
是一个成功的HRESULT
。
EXPECT_HRESULT_FAILED
EXPECT_HRESULT_FAILED(
expression
)
ASSERT_HRESULT_FAILED(
expression
)
验证expression
是一个失败的HRESULT
。
死亡断言
以下断言验证一段代码是否会导致进程终止。有关上下文,请参阅死亡测试。
这些断言产生一个新进程并在该进程中执行被测试的代码。这如何发生取决于平台和变量::testing::GTEST_FLAG(death_test_style)
,该变量从命令行标志--gtest_death_test_style
初始化。
- 在POSIX系统上,
fork()
(或Linux上的clone()
)用于生成子进程,之后- 如果变量的值为
"fast"
,则立即执行死亡测试语句。 - 如果变量的值为
"threadsafe"
,则子进程会重新执行单元测试二进制文件,就像最初调用它一样,但带有额外的标志,以仅运行正在考虑的单个死亡测试。
- 如果变量的值为
- 在Windows上,使用
CreateProcess()
API生成子进程,并重新执行二进制文件以仅运行正在考虑的单个死亡测试 - 非常类似于POSIX上的"threadsafe"
模式。
变量的其他值是非法的,会导致死亡测试失败。目前,该标志的默认值为 "fast"
。
如果死亡测试语句运行完成而没有终止,子进程仍然会终止,并且断言失败。
请注意,被测试的代码段可以是复合语句,例如
EXPECT_DEATH({
int n = 5;
DoSomething(&n);
}, "Error on line .* of DoSomething()");
EXPECT_DEATH
EXPECT_DEATH(
statement
,
matcher
)
ASSERT_DEATH(
statement
,
matcher
)
验证statement
导致进程以非零退出状态终止,并生成与matcher
匹配的stderr
输出。
参数matcher
可以是 matcher,用于 const std::string&
,或者是一个正则表达式(参见 正则表达式语法)——一个裸字符串 s
(没有 matcher)被视为 ContainsRegex(s)
,而不是 Eq(s)
。
例如,以下代码验证调用 DoSomething(42)
是否导致进程因包含文本 My error
的错误消息而终止
EXPECT_DEATH(DoSomething(42), "My error");
EXPECT_DEATH_IF_SUPPORTED
EXPECT_DEATH_IF_SUPPORTED(
statement
,
matcher
)
ASSERT_DEATH_IF_SUPPORTED(
statement
,
matcher
)
如果支持死亡测试,则行为与 EXPECT_DEATH
相同。 否则,不验证任何内容。
EXPECT_DEBUG_DEATH
EXPECT_DEBUG_DEATH(
statement
,
matcher
)
ASSERT_DEBUG_DEATH(
statement
,
matcher
)
在调试模式下,其行为与 EXPECT_DEATH
相同。 当不在调试模式下时(即定义了 NDEBUG
),仅执行 statement
。
EXPECT_EXIT
EXPECT_EXIT(
statement
,
predicate
,
matcher
)
ASSERT_EXIT(
statement
,
predicate
,
matcher
)
验证statement
导致进程以满足predicate
的退出状态终止,并生成与matcher
匹配的stderr
输出。
参数predicate
是一个函数或仿函数,它接受一个 int
退出状态并返回一个 bool
。 GoogleTest 提供了两个谓词来处理常见情况
// Returns true if the program exited normally with the given exit status code.
::testing::ExitedWithCode(exit_code);
// Returns true if the program was killed by the given signal.
// Not available on Windows.
::testing::KilledBySignal(signal_number);
参数matcher
可以是 matcher,用于 const std::string&
,或者是一个正则表达式(参见 正则表达式语法)——一个裸字符串 s
(没有 matcher)被视为 ContainsRegex(s)
,而不是 Eq(s)
。
例如,以下代码验证调用 NormalExit()
是否导致进程将包含文本 Success
的消息打印到 stderr
并以退出状态代码 0 退出
EXPECT_EXIT(NormalExit(), testing::ExitedWithCode(0), "Success");