GoogleTest 测试过滤实战:--gtest_filter 的 4 个场景与 3 个反直觉行为

发布时间:2026/8/24 16:40:37
GoogleTest 测试过滤实战:--gtest_filter 的 4 个场景与 3 个反直觉行为 GoogleTest 测试过滤实战--gtest_filter 的 4 个场景与 3 个反直觉行为【免费下载链接】googletestGoogleTest - Google Testing and Mocking Framework项目地址: https://gitcode.com/gh_mirrors/googl/googletest凌晨两点CI 又红了。1400 个用例里只有FooTest.Xyz挂了而你只想复现那一个 case。重新跑整个套件要 8 分钟等不起也看不出问题。把光标放到那行失败输出上直接上命令# 只跑 CI 里失败的那一个测试 ./foo_test --gtest_filterFooTest.Xyz两秒跑完红了就是红了绿的说明是环境问题。GoogleTest 的测试过滤就是干这个事的把执行范围从全量收敛到我真正关心的那几条。--gtest_filter 到底做了什么--gtest_filter等价于环境变量GTEST_FILTER接收一个通配表达式冒号分隔多个正模式可选地接一个减号后跟负模式测试的完整名套件名.测试名同时命中至少一个正模式、且不命中任何负模式时才会被执行。语法细节官方文档 docs/advanced.md 的 Running a Subset of the Tests 一节有完整说明下面直接进场景。如何只跑 CI 里那一个挂掉的测试CI 日志几百行定位到失败用例后复现是第一步。单条精确匹配就是套件名.测试名没有通配符也能用# 精确复现单个失败测试 ./foo_test --gtest_filterFooTest.Xyz想顺带断点调试加--gtest_break_on_failure失败时进程停在断点里变量和调用栈直接可查# 失败即停配合 gdb 用 ./foo_test --gtest_filterFooTest.Xyz --gtest_break_on_failure如果不知道套件名先用--gtest_list_tests看一眼目录它打印的就是后续过滤能用的全部名字。⚠️--gtest_filter和GTEST_FILTER功能相同但命令行参数覆盖环境变量。团队里有人export过GTEST_FILTER你在命令行显式传参时以你为准反过来你本地没传参、CI 却设了这个环境变量就会出现我本地是全量CI 只跑了一部分的诡异差异——排查时先echo $GTEST_FILTER。如何把依赖数据库的慢测试踢出日常循环改动只碰了缓存逻辑但全量里有 20 个要起数据库的慢测试日常跑一遍 4 分钟。按名字把慢测试圈出来日常命令反过来只跑它们日常循环就只跑其余部分# 日常开发排除所有名字含 Slow 的慢测试 ./foo_test --gtest_filter-*Slow*# 专属的慢测试 CI 任务只跑慢测试 ./foo_test --gtest_filter*Slow*⚠️ 这里有个反直觉点。减号在过滤串里只有一个位置第一个-之前全部算正模式之后全部算负模式。*-A*:*Slow*是并集*Slow*-*Integration*才是差集没有正负混排、各说各话的写法。另外想只跑死亡测试可以用*DeathTest*:*DeathTest/*别写*DeathTest.*——?只匹配单个字符点号在 GoogleTest 的过滤语法里不是正则通配符就是*任意串和?单字符两个。顺带一提遇到偶发失败的 flaky test过滤再叠--gtest_repeat是标准动作# 把可疑的测试重复跑 1000 次失败即停 ./foo_test --gtest_filterFooTest.Xyz --gtest_repeat1000 --gtest_break_on_failure配合--gtest_shuffle时每轮迭代会换随机种子重新打乱顺序时序类 bug 更容易现形。如何用一条命令把 DISABLED_ 的测试单独捞出来临时修不了的测试用DISABLED_前缀标记代码保留、默认不跑TEST(BarTest, DISABLED_TestFour) { ... } TEST(DISABLED_FoobarTest, Test1) { ... }某天你把它修好了想单独验证这一条而不是等全量# 临时跑所有被禁用的测试 ./foo_test --gtest_filter*DISABLED_* --gtest_also_run_disabled_tests# 只验证修好的那一条 ./foo_test --gtest_filterBarTest.DISABLED_TestFour --gtest_also_run_disabled_tests注意DISABLED_加在套件名上DISABLED_FoobarTest或测试名上效果一样过滤时按完整名匹配即可。⚠️ 最大的坑不加--gtest_also_run_disabled_tests即使过滤表达式精确命中了DISABLED_名字这条测试也静默不跑输出里没有被跳过的提示很容易误以为是通配符没写对。验证过滤是否生效看输出头部Running 1 test...这一行而不是猜。参数化测试的索引怎么过滤参数化测试的完整名长得像SeqP/ParamTest.TestX/0斜杠里夹着实例化名和参数索引*能跨过斜杠但你的过滤表达式得对得上这个结构# 跑某次实例化的全部参数化测试 ./foo_test --gtest_filterSeqP/* # 跑所有实例化里的 TestX不管第几组参数 ./foo_test --gtest_filter*/ParamTest.TestX/* # 跑所有实例的第 0 个参数 ./foo_test --gtest_filter*/*/0⚠️ 参数化测试参与分片时容易翻车过滤先于分片生效*/*/0筛完可能只剩 3 条测试而GTEST_TOTAL_SHARDS8的分片里有 5 个空跑。分片数先按过滤后剩余量来估别拍脑袋。--gtest_filter 和环境变量、分片、Bazel 打架怎么办先说处理顺序测试先过过滤选中的集合再分片每个分片只跑分配给自己的子集所有分片合起来每条恰好跑一次源码在 googletest/src/gtest.cc 的ShouldRunTest附近文档见 docs/advanced.md 的 Distributing Test Functions to Multiple Machines# 4 机分片第 2 号机只跑 FooTest GTEST_TOTAL_SHARDS4 GTEST_SHARD_INDEX1 ./foo_test --gtest_filterFooTest.*三个常见误解纠正一下误解实际情况负模式能写在任意位置减号只在整个过滤串中生效一次第一个-之前全是正模式之后全是负模式本地和 Bazel 下过滤行为一致Bazel 的--test_filter通过TESTBRIDGE_TEST_ONLY传入见 googletest/src/gtest.cc 中的注释优先级再高一层裸跑二进制和bazel test可能执行不同集合?像正则里的.过滤语法只有两个通配符*匹配任意串?只匹配单个字符没有点号通配优先级从高到低来源形式Bazel 桥接TESTBRIDGE_TEST_ONLY命令行--gtest_filter...环境变量GTEST_FILTER...同一来源里后面的模式不会覆盖前面的——正模式之间是并集负模式之间也是并集真正的减法只在正、负两个集合之间发生。速查表想干什么写法跑单个测试--gtest_filterFooTest.Xyz跑整个套件--gtest_filterFooTest.*名字含某关键字的并集--gtest_filter*Null*:*Constructor*排除某类测试--gtest_filter*DeathTest*换成--gtest_filter-*DeathTest.*更省事直接--gtest_filter-*DeathTest.*即可套件内排除单个--gtest_filterFooTest.*-FooTest.Bar跑被禁用测试--gtest_filter*DISABLED_* --gtest_also_run_disabled_tests参数化按实例--gtest_filterSeqP/*参数化按测试名--gtest_filter*/ParamTest.TestX/*参数化按参数索引--gtest_filter*/*/0过滤 分片GTEST_TOTAL_SHARDS4 GTEST_SHARD_INDEX1 ./foo_test --gtest_filter...过滤 重复抓 flaky--gtest_filterFooTest.Xyz --gtest_repeat1000【免费下载链接】googletestGoogleTest - Google Testing and Mocking Framework项目地址: https://gitcode.com/gh_mirrors/googl/googletest创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻