尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Log4Qt单元测试技巧:ListAppender与DebugAppender让日志代码可验证(完整指南)

Log4Qt单元测试技巧:ListAppender与DebugAppender让日志代码可验证(完整指南) Log4Qt单元测试技巧ListAppender与DebugAppender让日志代码可验证完整指南【免费下载链接】Log4QtLog4Qt - Logging for the Qt cross-platform application framework项目地址: https://gitcode.com/gh_mirrors/lo/Log4QtLog4Qt 是 Apache log4j 的 Qt 框架移植版为跨平台 Qt 应用提供成熟的日志记录能力。但很多开发者写业务逻辑时容易忽略一件事与日志交互的代码本身也容易被改坏。Log4Qt 自带两个专为验证场景设计的 Appender——ListAppender把日志事件收进内存列表供断言和DebugAppender把日志写到调试器输出配合它们你可以快速验证该打的日志是否真的打了、级别对不对、内容是否正确。为什么日志代码难以单元测试 传统上验证日志行为只有两种笨办法看文件配置 FileAppender 写日志文件测试后再去解析文件——慢、受文件系统影响、CI 上不稳定看控制台配置 ConsoleAppender 输出到屏幕靠肉眼确认——无法自动断言无法回归这两种方式都让日志断言停留在人工层面。Log4Qt 的解法是换掉输出目的地而不是换断言手段。ListAppender把日志事件收进内存 ListAppender源码位于src/log4qt/varia/listappender.h是所有验证型玩法的核心。它继承自 AppenderSkeleton但不写任何设备而是把每个被接受的LoggingEvent以原始对象形式追加到内部QListLoggingEvent中。它的三个关键 API 决定了测试能力API作用测试价值list()返回当前捕获事件的拷贝直接断言事件数量、级别、消息clearList()原子地取走并清空列表用例之间干净隔离可复用同一 AppendersetMaxCount(n)限制最大保留条数≤0 表示不限制防止长时间收集导致内存膨胀两个值得注意的设计细节不需要 LayoutrequiresLayout()返回 false因为存的是事件对象而非格式化字符串——所以你可以断言level()、message()、logger名等任何结构化字段而不必去解析字符串。全程线程安全list()、clearList()、append()都在同一把锁保护下执行多线程日志场景下放心调用。三步用 ListAppender 验证日志行为以验证某个 Logger 发出 WARN 级别消息为例auto *capture new ListAppender; capture-setName(QStringLiteral(capture)); capture-setMaxCount(100); capture-activateOptions(); Logger::logger(QStringLiteral(Test))-addAppender(AppenderSharedPtr(capture)); // 执行被测代码…… Logger::logger(QStringLiteral(Test))-warn(QStringLiteral(something happened)); const QListLoggingEvent events capture-list(); QCOMPARE(events.size(), 1); QCOMPARE(events.first().level(), Level::WARN_INT);项目自己的测试也是这么写的Log4Qt 的测试套件大量使用这个模式可以直接参考tests/mainthreadappendertest/tst_mainthreadappender.cpp创建 ListAppender 挂到 MainThreadAppender 后面用QCOMPARE(list-list().at(0).message(), ...)断言消息内容tests/asyncappendertest/tst_asyncappender.cpp验证 AsyncAppender 异步投递时事件是否完整到达下游tests/log4qttest/log4qttest.cpp甚至把 ListAppender 用作全局事件收集器loggingEvents()供整个测试类复用这些测试还展示了进阶技巧——继承 ListAppender 增强记录能力。例如 MainThreadAppender 测试中的ThreadCapturingListAppender在父类基础上额外记录每个事件到达时的线程从而验证事件是否被投递到了主线程。这说明 ListAppender 既是即用的断言工具也是自定义捕获 Appender 的优良基类。DebugAppender把日志送到你已经在看的调试输出 ️DebugAppender源码位于src/log4qt/varia/debugappender.h解决的是另一类问题开发调试时让日志出现在你已经盯着的地方。它的行为按平台区分Windows通过OutputDebugStringW发送到调试器——在 Visual Studio 输出窗口、DebugView 等工具中直接可见其他平台写入stderr与 ListAppender 相反DebugAppender必须有 LayoutrequiresLayout()返回 true因为它输出的是格式化后的字符串。它还提供了一个带 Layout 的便捷构造函数创建即可用auto *debug new DebugAppender(LayoutSharedPtr(new PatternLayout));适合 DebugAppender 的场景本地调试时不想再配文件直接让日志出现在调试器控制台CI 环境中把日志重定向到 stderr供构建系统收集需要格式化文本如 PatternLayout 带时间戳但又不关心断言的场景ListAppender vs DebugAppender如何选择 维度ListAppenderDebugAppender输出去向内存中的事件列表调试器 / stderr存储形式原始LoggingEvent对象格式化字符串可自动断言✅ 结构化断言❌ 仅人工查看需要 Layout否是必须典型用途单元测试、回归验证调试期观察、CI 日志收集一句话总结写自动化测试用 ListAppender调试期看输出用 DebugAppender两者可以共存于不同 Logger 上互不干扰。让测试代码更稳的 4 个实用技巧 用例之间清空列表每个测试用例开始时调用clearList()避免上一次的残留事件干扰本次断言给收集器设上限setMaxCount(100)之类防止异常情况下日志洪泛拖垮测试进程及时拆卸 Appender测试收尾时调用logger-removeAllAppenders()防止 Appender 泄漏到后续用例区分配置期事件ListAppender 的configuratorList属性置为 true 后removeAllAppenders()不会移除它专门用于收集配置过程中产生的日志——测试配置器行为时很有用相关源码与文档位置内容路径ListAppender 头文件src/log4qt/varia/listappender.hListAppender 实现src/log4qt/varia/listappender.cppDebugAppender 头文件src/log4qt/varia/debugappender.h主测试套件含 ListAppender 用法tests/log4qttest/log4qttest.cppMainThreadAppender 测试继承示例tests/mainthreadappendertest/tst_mainthreadappender.cppListAppender API 详解doc/api/ListAppender.mdDebugAppender API 详解doc/api/DebugAppender.md掌握 ListAppender 的收集—断言—清空循环你的日志相关代码就能像普通业务逻辑一样进入自动化回归而 DebugAppender 则保证了开发调试期日志触手可及。两者一静一动构成了 Log4Qt 可测试性的完整拼图。【免费下载链接】Log4QtLog4Qt - Logging for the Qt cross-platform application framework项目地址: https://gitcode.com/gh_mirrors/lo/Log4Qt创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表