如何使用Boost Unit Test框架测试Qt应用及断言语句放置位置
当然可以给Qt应用编写单元测试来覆盖这类随时被调用的函数!不过因为Qt依赖事件循环的特性(比如你代码里用了app.exec()),测试思路得和普通同步代码有点不一样,我给你几个实用的方案:
针对Qt应用的单元测试方案(以你的
deleteConnectionFromList函数为例) 1. 别让事件循环一直阻塞测试流程
你当前的测试代码直接调用app.exec()会卡住,因为事件循环会一直运行,没法执行后续的断言。可以用Qt的QTimer触发测试逻辑,或者手动控制事件循环的启停:
BOOST_AUTO_TEST_CASE(test_delete_connection) { int argc{}; QCoreApplication app(argc, nullptr); Server server; // 用QTimer让事件循环启动后再执行测试逻辑 QTimer::singleShot(0, [&]() { // 第一步:先调用addNewSocket添加测试用的socket QTcpSocket* testSocket = new QTcpSocket(); server.addNewSocket(testSocket); // 第二步:触发会调用deleteConnectionFromList的操作 // 比如模拟socket断开连接,或者直接调用相关触发逻辑 testSocket->disconnectFromHost(); // 第三步:在这里放你的断言! // 假设Server有个方法能获取当前连接列表的长度 BOOST_CHECK_EQUAL(server.connectionListSize(), 0); // 测试完成后退出事件循环,让测试继续往下走 app.quit(); }); app.exec(); }
2. 用信号槽捕获函数调用时机
如果deleteConnectionFromList是响应某个信号(比如QTcpSocket::disconnected)被调用的,你可以用信号槽机制来精准触发断言:
BOOST_AUTO_TEST_CASE(test_delete_triggered) { int argc{}; QCoreApplication app(argc, nullptr); Server server; QTcpSocket* testSocket = new QTcpSocket(); // 绑定socket断开的信号,在槽里执行断言 QObject::connect(testSocket, &QTcpSocket::disconnected, [&]() { // 确保deleteConnectionFromList执行完毕(处理队列中的槽函数) QCoreApplication::processEvents(); BOOST_CHECK_EQUAL(server.connectionListSize(), 0); app.quit(); }); server.addNewSocket(testSocket); testSocket->disconnectFromHost(); // 触发断开逻辑,间接调用deleteConnectionFromList app.exec(); }
3. 给Server类加个测试友好的小改造(如果允许的话)
如果deleteConnectionFromList是私有函数,或者你没法直接验证它的执行结果,可以给Server类做微小调整:
- 新增一个
int connectionListSize()方法,返回当前连接列表的长度,方便断言 - 或者在
deleteConnectionFromList里发射一个自定义信号connectionDeleted(QTcpSocket*),测试代码监听这个信号来做断言
关键注意事项
- 一定要记得在测试完成后调用
app.quit(),否则事件循环会一直运行,测试无法结束 - 如果涉及多线程操作(比如Qt网络模块的后台线程),要用
QCoreApplication::processEvents()或者QWaitCondition等待操作完成,避免断言时机过早 - 用Boost.Test结合Qt时,要确保测试项目正确链接Qt核心库和Boost.Test库
内容的提问来源于stack exchange,提问作者Miszo97
相关产品推荐
相关产品推荐

