0.引言
1.初始化
- 添加需要的头文件
#include <glog/logging.h>
- 设置使用文档(可选)
google::SetUsageMessage("How to use");
- 设置版本(可选)
google::SetVersionString("1.0.0");
- 配置 LOG
FLAGS_logtostderr = true; // 设置 log 输出到标准错误
FLAGS_colorlogtostderr = true; // 设置 log 使用颜色
- 解析命令行
google::ParseCommandLineFlags(&argc, &argv, true);
- 初始化 google-glog
google::InitGoogleLogging(argv[0]);
- 设置输出目录
FLAGS_log_dir = "./log" ;
- 使用 google-glog
LOG(INFO) << "This is INFO message."
2.测试功能
头文件:#include "gtest/gtest.h"
- TEST(测试集合名称,测试案例名称)//这两个名称都是自己起的
- TEST(LineSegment2dTest, Accessors)
Apollo中的使用:
TEST(LineSegment2dTest, Accessors) {
const LineSegment2d ls({1, 2}, {5, 4});
EXPECT_NEAR(ls.length(), std::sqrt(20.0), 1e-5);
EXPECT_NEAR(ls.length_sqr(), 20.0, 1e-5);
EXPECT_NEAR(ls.center().x(), 3, 1e-5);
EXPECT_NEAR(ls.center().y(), 3, 1e-5);
EXPECT_NEAR(ls.heading(), std::atan2(2, 4), 1e-5);
EXPECT_NEAR(ls.cos_heading(), 4.0 / std::sqrt(20.0), 1e-5);
EXPECT_NEAR(ls.sin_heading(), 2.0 / std::sqrt(20.0), 1e-5);
EXPECT_EQ(ls.DebugString(),
"segment2d ( start = vec2d ( x = 1 y = 2 ) end = vec2d ( x = 5 "
"y = 4 ) )");
}
在测试函数中,gtest 提供了EXPECT_*和ASSERT_*这两种风格的断言:
TEST(MyTest, Add)
{
EXPECT_EQ(1 + 1, 2);
ASSERT_EQ(1 + 1, 2);
}
那么这两种断言有什么区别呢?如果ASSERT_*执行失败了,会导致当前的测试函数立即返回。而EXPECT_*如果执行失败了,并不会导致测试函数返回。
- gtest 提供了 8 个ASSERT_*断言,分别是ASSERT_TRUE()、ASSERT_FALSE()、ASSERT_EQ()、ASSERT_NE()、ASSERT_LT()、ASSERT_LE()、ASSERT_GT()和ASSERT_GE()。
- EXPECT_*的断言同样也有 8 个,分别是ASSERT_TRUE()、ASSERT_FALSE()、EXPECT_EQ()、EXPECT_NE()、EXPECT_LT()、EXPECT_LE()、EXPECT_GT()和EXPECT_GE()。 现在扩展了不止8个了。
- EXPECT_NEAR(ls.length(), std::sqrt(20.0), 1e-5);测试两者误差不超过1e-5
3.CHECK宏
头文件:#include <glog/logging.h>
glog 提供了CHECK()宏帮助我们检查程序的错误,当CHECK()的条件不满足时,它会记录FATAL日志并终止程序:
CHECK(Condition expression):当条件表达式不成立的时候,会输出一个类型为FATAL的log信息
CHECK(fun() == 0) << "Call fun() failed!";
- 与assert()不同的是,无论程序是否开启NODEBUG,CHECK()都会执行。除了CHECK(),glog 还提供其它的宏,包括CHECK_EQ()、CHECK_NE()、CHECK_LE()、CHECK_LT()、CHECK_GE()和CHECK_GT()。
#define CHECK_EQ(x,y) CHECK_OP(x,y,EQ,==)
#define CHECK_NE(x,y) CHECK_OP(x,y,NE,!=)
#define CHECK_LE(x,y) CHECK_OP(x,y,LE,<=)
#define CHECK_LT(x,y) CHECK_OP(x,y,LT,<)
#define CHECK_GE(x,y) CHECK_OP(x,y,GE,>=)
#define CHECK_GT(x,y) CHECK_OP(x,y,GT,>)
ϵ \epsilon ϵ
- 在判断指针是否为NULL时,需要注意先将NULL转换成为相应的类型,然后再进行比较:
CHECK_EQ(some_ptr, static_cast<SomeType*>(NULL)) << "some_ptr is a null pointer";
更好的办法是用 CHECK_NOTNULL 宏:
CHECK_NOTNULL(some_ptr);
some_ptr->DoSomething();
glog 还提供了其它宏用来检查char *类型的字符串,包括CHECK_STREQ()、CHECK_STRNE()、CHECK_STRCASEEQ()和CHECK_STRCASENE(),带有 CASE 的版本表示大小写不敏感的。传递NULL值给这些宏是安全的。
另外,可以使用CHECK_DOUBLE_EQ()检查两个浮点数是否相等,允许出现比较小的误差。如果需要自己提供可以接受的误差范围,可以使用CHECK_NEAR(),它的第三个参数为用户指定的误差范围。
4.日志级别
- 可以指定下面这些级别(按严重性递增排序):
INFO, WARNING, ERROR, FATAL
- 打印 FATAL 消息会在打印完成后终止程序。和其他日志库类似,级别更高的日志会在同级别和所有低级别的日志文件中打印。
- DFATAL 级别会在调试模式(没有定义 NDEBUG 宏)中打印 FATAL 日志,但是会自动降级为 ERROR 级别,而不终止程序。
如果不指定的话,Glog输出到文件:
/tmp/<program name>.<hostname>.<user name>.log.<severity level>.<date>-<time>.<pid>
(比如 /tmp/hello_world.example.com.hamaji.log.INFO.20080709-222411.10474
)。
默认情况下,Glog对于 ERROR 和 FATAL 级别的日志会同时输出到std::err。
LOG(INFO) << "Found " << num_cookies << " cookies";
5.日常用法
int main(int argc, char** argv) {
google::InitGoogleLogging(argv[0]);
google::InstallFailureSignalHandler();
FLAGS_alsologtostderr = true;
FLAGS_colorlogtostderr = true;
LOG(INFO) << "Hello world!";
CHECK(argc >= 3) << "Usage: " << argv[0]
<< " [path for load_image] [path for save_image]";
cv::Mat image = cv::imread(argv[1], cv::IMREAD_COLOR);
CHECK(image.channels() == 3);
cv::Mat result_image;
do_something(image, result_image);
cv::imwrite(argv[2], result_image);
google::ShutdownGoogleLogging();
return 0;
}