【c++中间件】gflags && gtest
文章目录
I. 基础工具安装
sudo apt-get install vim
sudo apt-get install gcc g++
sudo apt-get install gdb
sudo apt-get install make cmake
sudo apt-get install lrzsz
sudo apt-get install git
II. gflags
一、gflags介绍与安装
gflags 是 Google 开发的一个开源库,用于 C++ 应用程序中命令行参数的声明、定义和解析。gflags 库提供了一种简单的方式来添加、解析和文档化命令行标志(flags),使得程序可以根据不同的运行时配置进行调整。它具有如下几个特点:
- 易于使用:
gflags提供了一套简单直观的API来定义和解析命令行标志,使得开发者可以轻松地为应用程序添加新的参数。 - 自动帮助和文档:
gflags可以自动生成每个标志的帮助信息和文档,这有助于用户理解如何使用程序及其参数。 - 类型安全:
gflags支持多种数据类型的标志,包括布尔值、整数、字符串等,并且提供了类型检查和转换。 - 多平台支持:
gflags可以在多种操作系统上使用,包括Windows、Linux和macOS。 - 可扩展性:
gflags允许开发者自定义标志的注册和解析逻辑,提供了强大的扩展性。
官方文档: https://gflags.github.io/gflags/
代码仓库:https://github.com/gflags/gflags.git
安装命令:
sudo apt-get install libgflags-dev
验证是否安装的命令:
ls /usr/include/gflags/
whereis libgflags.so
二、gflags使用
1. 头文件
#include <gflags/gflags.h>
2. 定义参数
利用 gflag 提供的宏定义来定义参数。该宏的 3 个参数分别为 命令行参数名、参数默认值、参数的帮助信息。
DEFINE_bool(reuse_addr, true, "是否开始网络地址重用选项");
DEFINE_int32(log_level, 1, "日志等级:1-DEBUG,2-WARN,3-ERROR");
DEFINE_string(log_file, "stdout", "日志输出位置设置,默认为标准输出");
gflags 支持定义多种类型的宏函数:
DEFINE_bool
DEFINE_int32
DEFINE_int64
DEFINE_uint64
DEFINE_double
DEFINE_string
3. 使用定义好的参数
我们可以在程序中 通过 FLAGS_name 像正常变量一样访问标志参数。比如在上面的例子中,我们可以通过 FLAGS_reuse_addr 和 FLAGS_log_level 变量来访问命令行参数。
4. 初始化所有参数
当我们定义好参数后,需要告诉可执行程序去处理解析命令行传入的参数,使得 FLAGS_* 变量能得到正确赋值。我们需要在 main 函数中,调用下面的函数来解决命令行传入的所有参数:
google::ParsecommandLineFlags(&argc, &argv, true);
5. 使用例子
#include <gflags/gflags.h>
#include <iostream>
DEFINE_string(ip, "127.0.0.1", "这是服务器的监听ip地址,格式:127.0.0.1");
DEFINE_int32(port, 8800, "这是服务器的监听端口,格式:8800");
DEFINE_bool(debug_enable, true, "是否启用调试模式,格式:true/false");
int main(int argc, char* argv[])
{
google::ParseCommandLineFlags(&argc, &argv, true);
std::cout << FLAGS_ip << std::endl;
std::cout << FLAGS_port << std::endl;
std::cout << FLAGS_debug_enable << std::endl;
return 0;
}
6. 其他注意事项
-
配置文件 设置参数时:
-
不要出现多余的空格
-
文件格式为
.conf,内容如下所示:// main.conf文件 -ip="192.168.0.1" -port=9090 -debug_enable=true -
使用方法:
./main --flagfile main.conf
-
-
命令行设置参数的格式:
./main --ip="123456" --port=8080 --debug_enable=false -
编译文件时 记得链接动态库:
g++ main.cc -lgflags -
使用下述命令可以显示帮助信息:
./main --help
Ⅲ、gtest的介绍与安装
GTest 是一个跨平台的 C++单元测试框架,由 google 公司发布。gtest 是为了在不同平台上为编写 C++ 单元测试而生成的。它提供了丰富的断言、致命和非致命判断、参数化等等测试所需的宏,以及全局测试,单元测试组件。
主要特性如下所示:
- 跨平台支持:支持
Linux、Windows、MacOS等主流平台。 - 易于使用:简单直观的语法,容易上手。
- 丰富的断言:支持多种断言(如比较、布尔、字符串等)。
- 测试组织:支持分组、参数化测试。
- 灵活的报告格式:可生成
XML测试报告,方便与CI/CD集成。 - Mock 支持:通过
Google Mock实现更复杂的单元测试。
安装命令如下所示:
sudo apt-get install libgtest-dev
然后可以用下面指令验证是否安装成功:
ls /usr/include/gtest/
whereis libgtest.a
Ⅳ、gtest使用
1. 头文件 && 链接库
注意在编译的时候要链接库!
// 头文件:
include <gtest/gtest.h>
// makefile文件:
g++ -std=c++17 -o $@ $^ -lgtest
2. 框架初始化接口
testing::InitGoogleTest(&argc, argv);
3. 调用测试样例
一般我们会在程序最后才调用测试样例,故可以直接在主函数的 return 语句中调用!
...
int main()
{
...
return RUN_ALL_TESTS(); // 在程序最后进行测试样例调用
}
4. TEST宏
-
TEST:主要用来创建一个 简单测试, 它定义了一个测试函数, 在这个函数中可以使用任何
C++代码并且使用框架提供的断言进行检查。// 1. 同测试下多个测试样例不能同名! // 2. 两个名称都是可以用中文的,只要编译器支持正确的编码处理即可! TEST(TestSuiteName, TestName) { // 测试代码 EXPECT_TRUE(true); // 示例断言 } -
TEST_F:主要用来进行 多样测试,适用于多个测试场景如果需要相同的数据配置的情况, 即相同的数据测不同的行为。
FixtureName:测试夹具类名称,继承自::testing::Test。SetUp和TearDown:分别在每个测试用例运行前和运行后执行。
// 样例示范 #include <gtest/gtest.h> class MathTestFixture : public ::testing::Test { protected: void SetUp() override { // 初始化共享资源 x = 10; y = 20; } void TearDown() override { // 清理工作 } int x; int y; }; TEST_F(MathTestFixture, Addition) { EXPECT_EQ(x + y, 30); // 检查 x + y 是否等于 30 } TEST_F(MathTestFixture, Multiplication) { EXPECT_EQ(x * y, 200); // 检查 x * y 是否等于 200 }
5. 断言宏
GTest 中的断言的宏可以分为两类:
• ASSERT_系列:如果当前点检测失败,则退出当前测试函数。
• EXPECT_系列:如果当前点检测失败,仍然继续往下执行。
下面是常用的断言:
- 基本比较:
EXPECT_EQ(val1, val2):期望 val1 == val2EXPECT_NE(val1, val2):期望 val1 != val2EXPECT_LT(val1, val2):期望 val1 < val2EXPECT_LE(val1, val2):期望 val1 <= val2EXPECT_GT(val1, val2):期望 val1 > val2EXPECT_GE(val1, val2):期望 val1 >= val2
- 布尔表达式:
EXPECT_TRUE(condition):期望 condition 为 trueEXPECT_FALSE(condition):期望 condition 为 false
- 字符串:
EXPECT_STREQ(str1, str2):期望 str1 和 str2 内容相同EXPECT_STRNE(str1, str2):期望 str1 和 str2 内容不同
- 浮点数:
EXPECT_FLOAT_EQ(val1, val2):期望 val1 和 val2 近似相等(单精度)EXPECT_DOUBLE_EQ(val1, val2):期望 val1 和 val2 近似相等(双精度)
6. 举个例子
上面 TEST_F 已经举过例子了,这里就举一下 TEST 宏的例子:
#include <iostream>
#include <string>
#include <gtest/gtest.h>
using namespace std;
int add(int a, int b)
{
return a + b;
}
TEST(测试名称, 加法用例测试) {
ASSERT_EQ(add(1, 2), 3);
ASSERT_LT(add(1, 2), 4);
ASSERT_LT(add(1, 2), 2);
ASSERT_NE(add(1, 2), 2);
cout << "执行到尾部!" << endl;
}
TEST(测试名称, 字符串拼接) {
std::string a = "Hello, ";
std::string b = "World!";
ASSERT_EQ(a + b, "Hello, World!"); // 检查字符串拼接
}
int main(int argc, char* argv[])
{
// 初始化
testing::InitGoogleTest(&argc, argv);
// 运行所有测试样例
return RUN_ALL_TESTS();
}
再写个 makefile 文件:
main : main.cc
g++ -std=c++17 -o $@ $^ -lgtest
然后执行可以得到下面的信息:

可以发现并没有执行输出语句,故没有执行到尾部,换成 EXPECT 宏则可以!
更多推荐


所有评论(0)