赞
踩
gtest中assert的头文件: gtest/gtest.h
EXPECT_
和ASSERT_
两种形式,EXPECT_
产生非致命错误,ASSERT_
产生致命错误并中断当前函数;所有断言宏支持使用重载<<的流输出
ASSERT_EQ(x.size(), y.size()) << "Vectors x and y are of unequal length";
for (int i = 0; i < x.size(); ++i) {
EXPECT_EQ(x[i], y[i]) << "Vectors x and y differ at index " << i;
}
对断言FAIL*
和ASSERT*
的一个限制是,只能用在返回类型为void的函数中(如果是非void返回类型编译不通过)。所以对于返回类型为非void的函数,可以用参数代替。
EXPECT_THAT(value,matcher)
ASSERT_THAT(value,matcher)
验证value是否和matcher匹配,matcher参考这里
示例
EXPECT_THAT("HelloWorld", ::testing::StartsWith("Hello")); // 验证字符串HelloWorld是否以Hello开头
EXPECT_TRUE(condition)
ASSERT_TRUE(condition)
验证condition是否为true,true为通过
EXPECT_FALSE(condition)
ASSERT_FALSE(condition)
验证condition是否为false
用来比较两个值,参数中的两个值必须是可以比较的(支持比较运算符)
如果一个参数支持<<操作符,当比较失败时会被调用打印参数,否则gtest会用它认为最好的方式打印,具体参考https://google.github.io/googletest/advanced.html#teaching-googletest-how-to-print-your-values
支持宽字符(wstring)和窄字符(string)
浮点型数据不能比较
EXPECT_EQ(val1,val2)
ASSERT_EQ(val1,val2)
验证val1==val2,不相等则出错。如果比较两个C风格数组,比较的是两个数组的地址而不是数组值。比较字符串使用EXPECT_STREQ
。比较指针使用EXPECT_EQ(ptr, nullptr)
而不是EXPECT_EQ(ptr, NULL)
EXPECT_NE(val1,val2)
ASSERT_NE(val1,val2)
验证val1 != val2。同样,如果是指针比较,对比的是内存中的地址值,而不是是否有相同的值。
比较指针则使用EXPECT_NE(ptr, nullptr)
代替EXPECT_NE(ptr, NULL)
EXPECT_LT(val1,val2)
ASSERT_LT(val1,val2)
验证 val1<val2.
EXPECT_LE(val1,val2)
ASSERT_LE(val1,val2)
验证 val1<=val2.
EXPECT_GT(val1,val2)
ASSERT_GT(val1,val2)
验证 val1>val2.
EXPECT_GE(val1,val2)
ASSERT_GE(val1,val2)
验证 val1>=val2.
这里的字符串比较用于两个C风格的字符串,如果对比两个string对象,使用 EXPECT_EQ
或者EXPECT_NE
。
如果要将C数组和NULL做对比, 使用EXPECT_EQ(c_string, nullptr)
或者EXPECT_NE(c_string, nullptr)
.
EXPECT_STREQ(str1,str2)
ASSERT_STREQ(str1,str2)
比较str1和str2是否有相同的值
EXPECT_STRNE(str1,str2)
ASSERT_STRNE(str1,str2)
比较str1和str2是否不同
EXPECT_STRCASEEQ(str1,str2)
ASSERT_STRCASEEQ(str1,str2)
忽略大小写比较str1和str2是否有相同的值
EXPECT_STRCASENE(str1,str2)
ASSERT_STRCASENE(str1,str2)
忽略大小写比较str1和str2是否有不同的值
浮点型由于精度舍入原因,使用EXPECT_EQ 并不能很准确判断,Google test提供了专用于比较浮点型比较的断言。
EXPECT_FLOAT_EQ(val1,val2)
ASSERT_FLOAT_EQ(val1,val2)
比较float类型,保留后四位
EXPECT_DOUBLE_EQ(val1,val2)
ASSERT_DOUBLE_EQ(val1,val2)
比较double类型,保留后四位
EXPECT_NEAR(val1,val2,abs_error)
ASSERT_NEAR(val1,val2,abs_error)
比较两个值的误差的绝对值是否超过abs_error
TEST(TestFloatCase, float_case01) {
float a = 2.34732, b = 2.34732;
double c = 6.75433, d = 9.634638;
EXPECT_FLOAT_EQ(a, b); // success
EXPECT_DOUBLE_EQ(c, d); // fail
EXPECT_NEAR(a, c, 5); // success
EXPECT_NEAR(c, a, -5); // fail
}
这种是直接生成成功和失败,代替了表达式或者值。常用在控制流,而不是需要判断boolean的表达式来决定test的成功和失败,举例如下
switch(expression) {
case 1:
ADD_FAILURE() << "..";
case 2:
....
default:
FATAL() << "We shouldn't get here.";
SUCCEED()
生成一个success,不会有用户可见的输出,后续有可能会有输出
FAIL()
生成一个fatal failure,从当前函数退出,不会执行后面的代码,只能用在返回值为void的函数中。
ADD_FAILURE()
生成一个nonfatal failure,它会允许当前函数继续执行,这是与FAIL的区别
ADD_FAILURE_AT(file_path,line_number)
在一个文件的指定行生成一条nonfatal failure
void test_func1() {
SUCCEED() << "------------gtest SUCCEED------------";
ADD_FAILURE() << "----------gtest ADD_FAILURE--------------";
ADD_FAILURE_AT("/home//iLearning/code/gtest/gtest_project/src/doc.txt", 2) << "--------gtest ADD_FAILURE_AT---------";
}
输出如下:
结果证明,SUCCEED()没有输出任何信息,ADD_FAILURE()和ADD_FAILURE_AT(file_path,line_number) 都有failure的输出。
验证是否会抛出异常
EXPECT_THROW(statement,exception_type)
ASSERT_THROW(statement,exception_type)
验证statement会抛出类型为exception_type的异常
EXPECT_ANY_THROW(statement)
ASSERT_ANY_THROW(statement)
验证statement会抛出任何类型的异常
EXPECT_NO_THROW(statement)
ASSERT_NO_THROW(statement)
验证statement不会抛出异常
定义异常类:
class MyException : public std::exception {
public:
MyException(string_view str): str_(str) {}
const char* what() const _GLIBCXX_NOTHROW override {
return str_.c_str();
}
private:
std::string str_;
};
异常调用函数:
void test_exception_func0() {
throw MyException {"hello"};
}
void test_exception() {
try {
throw MyException {"hello"};
}
catch(const MyException& e) {
std::cerr << "e.what()" << '\n';
}
}
断言:
TEST(Exception_TestSuite, test00) {
EXPECT_THROW(test_exception_func0, MyException);
}
TEST(Exception_TestSuite, test01) {
EXPECT_ANY_THROW(test_exception_func0);
}
TEST(Exception_TestSuite, test02) {
EXPECT_NO_THROW(test_exception_func0);
}
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,如果pred返回true则断言成功,否则失败,如果失败了,它会打印每个参数值。pred是一个函数或者函数对象,可以接受在断言宏中给定的其他参数。
bool MutuallyPrime(int i, int j) {
return i > j;
}
const int a = 2;
const int b = 3;
const int c = 4;
TEST(TestPredSuite, pred_test) {
EXPECT_PRED2(MutuallyPrime, b, a);
EXPECT_PRED2(MutuallyPrime, c, b);
}
输出如下:
注意:如果谓词是重载函数或者模板函数,断言宏可能无法识别,需要显式指定函数参数类型
重载函数:
MutuallyPrime重载,注意EXPECT_PRED*中指定函数的写法
bool MutuallyPrime(int i, int j) {
return i > j;
}
bool MutuallyPrime(char i, int j) {
return i > j;
}
const int a = 2;
const int b = 3;
const int c = 4;
const char d = 5;
TEST(TestPredSuite, pred_test) {
EXPECT_PRED2(static_cast<bool(*)(char, int)>(MutuallyPrime), d, a);
EXPECT_PRED2(static_cast<bool(*)(int, int)>(MutuallyPrime), c, b);
}
模板函数作为谓词,注意在EXPECT_PRED2中第一个参数需要用括号:
const int a = 2;
const int b = 3;
const int c = 4;
const char d = 5;
template<typename T1, typename T2>
bool CompareVal(T1 t1, T2 t2) {
return t1 > t2;
}
TEST(TestPredSuite, pred_test) {
EXPECT_PRED2((CompareVal<char, int>), d, a);
EXPECT_PRED2((CompareVal<int, int>), c, b);
}
EXPECT_PRED1不需要括号
template <typename T>
bool IsNegative(T x) {
return x < 0;
}
TEST(AssertionTest4, pred_test0) {
EXPECT_PRED1(IsNegative<int>, 1);
}
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)
谓词签名如下:
testing::AssertionResult PredicateFormatter(const char* expr1,
const char* expr2,
...
const char* exprn,
T1 val1,
T2 val2,
...
Tn valn);
目测通过这个方式可以输出像输出的任何信息。
使用返回类型为::test::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();
}
AssertionResult 对象可以使用 << 运算符输出信息。
为了在boolear断言中,输出更加可读的信息,可以使用返回AssertionResult代替bool的predicate函数:
任何测试导致进程以一种期望的方式终止叫做死亡测试。注意抛出异常不能称为死亡测试,因为调用部分可以捕获到。
死亡断言会生成新的子进程,并在子进程中执行代码,具体会做些什么依赖平台和变量::testing::GTEST_FLAG(death_test_style), 这个变量由命令行flag --gtest_death_test_style初始化:
EXPECT_DEATH(statement,matcher)
ASSERT_DEATH(statement,matcher)
验证statement 以非0的状态离开并退出进程,并且stderr输出信息匹配matcher。matcher 既可以是一个const std::string&的matcher 对象,也可以是一个正则表达式:一个字符串s被认为是 ContainsRegex(s),而不是Eq(s)。
示例:
void DoSomething(int* n) {
std::cerr << "Error on line .sss of DoSomething()"; // 注意:要用stderr输出,类似std::cout的输出都会导致验证失败
abort();
}
TEST(AssertionTest5, death_test00) {
EXPECT_DEATH({
int n = 5;
DoSomething(&n);
}, "Error on line .* of DoSomething()");
}
EXPECT_DEATH_IF_SUPPORTED(statement,matcher)
ASSERT_DEATH_IF_SUPPORTED(statement,matcher)
如果支持death test则和EXPECT_DEATH一样,否则什么都不做。
EXPECT_DEBUG_DEATH(statement,matcher)
ASSERT_DEBUG_DEATH(statement,matcher)
在debug模式下和EXPECT_DEATH一样,非debug模式下(i.e. NDEBUG is defined), 只执行statement.
EXPECT_EXIT(statement,predicate,matcher)
ASSERT_EXIT(statement,predicate,matcher)
验证statement用一个符合predicate的int类型的exit status引起进程终止, 并产生匹配matcher的stderr标准错误输出信息。谓词predicate 是一个 function or functor接受一个int类型的exit status参数,并返回一个bool类型。 GoogleTest提供两个predicate用于处理常见的情形:
// 进程退出状态如果等于exit_code则返回true
::testing::ExitedWithCode(exit_code);
// 杀死进程的信号为signal_number则返回true,windows下不可用
::testing::KilledBySignal(signal_number);
退出状态示例:
void NormalExit() {
std::cerr << "hi,I am happy";
_exit(1);
}
TEST(AssertionTest6, death_test01) {
EXPECT_EXIT(NormalExit(), testing::ExitedWithCode(1), "hi,I am happy"); // matcher和exit code任一不符合会导致测试fail
}
退出信号示例:
void KillProcess() {
std::cerr << "I am not happy" << std::endl;
abort();
}
TEST(MyDeathTest, KillProcess) {
EXPECT_EXIT(KillProcess(), testing::KilledBySignal(SIGABRT), // matcher和退出信号任一不一致会导致测试fail
"I am not happy");
}
一般有两种形式,“fast"和“threadsafe”。默认为fast。threadsafe会保证在线程安全的 场景下进行测试。可以通过GTEST_FLAG_SET(death_test_style, "threadsafe");
来设置。
可以在main中为每个死亡测试设置,或单独为某个测试设置。
int main(int argc, char** argv) {
testing::InitGoogleTest(&argc, argv);
GTEST_FLAG_SET(death_test_style, "fast");
return RUN_ALL_TESTS();
}
TEST(MyDeathTest, TestOne) {
GTEST_FLAG_SET(death_test_style, "threadsafe");
ASSERT_DEATH(ThisShouldDie(), ""); // This test is run in the "threadsafe" style:
}
TEST(MyDeathTest, TestTwo) {
ASSERT_DEATH(ThisShouldDie(), ""); // This test is run in the "fast" style:
}
::testing::StaticAssertTypeEq<T1, T2>(); 判断类型T1和T2是否相同。如果不同编译会报错,如果相同不会有任何操作。这在模板代码中非常有用。
template<typename T1, typename T2>
class TemTest {
public:
TemTest(const T1& t1, const T2& t2) {
::testing::StaticAssertTypeEq<T1, T2>();
}
};
void test {
TemTest<int, string> t(1, "good");
}
编译报错:
注意,这个是在编译阶段判断的,如果是在模板类的成员函数等没有在编译阶段具现化则不会报错。如下例所示,不会出现类型不同的报错。
template<typename T1, typename T2> class TemTest {
public:
TemTest(const T1& t1, const T2& t2) {
std::cout << "t1: " << t1 << ", t2: " << t2 << std::endl;
}
void Bar() {
::testing::StaticAssertTypeEq<T1, T2>();
}
};
void test {
TemTest<int, string> t(1, "good");
}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。