#include #include "../ModbusMatser/modbus_master.h" // 单元测试类,用于测试 ModbusRTUMaster 类的解析函数 class Test_Modbus : public QObject { Q_OBJECT public: Test_Modbus(); ~Test_Modbus(); private slots: // 测试用例声明 void test_parseResponse(); // 测试 parseResponse 函数 void test_parseReadCoilsResponse(); // 测试 parseReadCoilsResponse 函数 void test_parseReadHoldingRegistersResponse(); // 测试 parseReadHoldingRegistersResponse 函数 }; // 构造函数 Test_Modbus::Test_Modbus() { } // 析构函数 Test_Modbus::~Test_Modbus() { } // 测试 parseResponse 函数 void Test_Modbus::test_parseResponse() { ModbusRTUMaster modbus; quint8 slaveAddr, funcCode, errorCode; QVector parsedData; // 测试用例 1: 正常读保持寄存器响应(功能码03,2个寄存器) // 帧格式: [从站地址:01] [功能码:03] [字节数:04] [数据:0001 0003] [CRC] QByteArray response = QByteArray::fromHex("01030400010003EBF2"); modbus.setRegCount(2); // 设置期望的寄存器数量 QVERIFY(modbus.parseResponse(response, slaveAddr, funcCode, parsedData, errorCode)); QCOMPARE(slaveAddr, static_cast(0x01)); // 验证从站地址 QCOMPARE(funcCode, static_cast(0x03)); // 验证功能码 QCOMPARE(errorCode, ModbusRTUMaster::NO_ERROR); // 验证无错误 QCOMPARE(parsedData.size(), 2); // 验证数据长度 QCOMPARE(parsedData[0], static_cast(0x0001)); // 验证寄存器1 QCOMPARE(parsedData[1], static_cast(0x0003)); // 验证寄存器3 // 测试用例 2: 正常读线圈响应(功能码01,8个线圈) // 帧格式: [从站地址:01] [功能码:01] [字节数:01] [数据:FF] [CRC] modbus.setCoilCount(8); // 设置期望的线圈数量 response = QByteArray::fromHex("010101FF11C8"); QVERIFY(modbus.parseResponse(response, slaveAddr, funcCode, parsedData, errorCode)); QCOMPARE(slaveAddr, static_cast(0x01)); // 验证从站地址 QCOMPARE(funcCode, static_cast(0x01)); // 验证功能码 QCOMPARE(errorCode, ModbusRTUMaster::NO_ERROR); // 验证无错误 QCOMPARE(parsedData.size(), 8); // 验证数据长度 for (int i = 0; i < 8; ++i) { QCOMPARE(parsedData[i], static_cast(1)); // 验证所有线圈为1 } // 测试用例 3: 错误响应(功能码83,非法功能) // 帧格式: [从站地址:01] [功能码:83] [错误码:01] [CRC] parsedData.clear(); response = QByteArray::fromHex("01830180F0"); QVERIFY(modbus.parseResponse(response, slaveAddr, funcCode, parsedData, errorCode)); QCOMPARE(slaveAddr, static_cast(0x01)); // 验证从站地址 QCOMPARE(funcCode, static_cast(0x83)); // 验证功能码 QCOMPARE(errorCode, static_cast(0x01)); // 验证错误码 QCOMPARE(parsedData.size(), 0); // 验证无数据 // 测试用例 4: 数据帧过短(无效帧) response = QByteArray::fromHex("0103"); // 只有2字节,少于最小长度 QVERIFY(!modbus.parseResponse(response, slaveAddr, funcCode, parsedData, errorCode)); // 测试用例 5: CRC错误 // 帧格式: [从站地址:01] [功能码:03] [字节数:04] [数据:0001 0004] [错误CRC] response = QByteArray::fromHex("01030400010004AB30"); QVERIFY(!modbus.parseResponse(response, slaveAddr, funcCode, parsedData, errorCode)); // 测试用例 6: 不支持的功能码 // 帧格式: [从站地址:01] [功能码:05] [数据] [CRC] response = QByteArray::fromHex("01050400010002D6E9"); QVERIFY(!modbus.parseResponse(response, slaveAddr, funcCode, parsedData, errorCode)); } // 测试 parseReadCoilsResponse 函数 void Test_Modbus::test_parseReadCoilsResponse() { ModbusRTUMaster modbus; QVector coils; // 测试用例 1: 正常读线圈响应(8个线圈全1) // 数据格式: [字节数:01] [数据:FF] modbus.setCoilCount(8); QByteArray responseData = QByteArray::fromHex("01FF"); QVERIFY(modbus.parseReadCoilsResponse(responseData, coils)); QCOMPARE(coils.size(), 8); // 验证线圈数量 for (int i = 0; i < 8; ++i) { QCOMPARE(coils[i], true); // 验证每个线圈状态为1 } // 测试用例 2: 正常读线圈响应(5个线圈,前5位为1) // 数据格式: [字节数:01] [数据:1F] modbus.setCoilCount(5); responseData = QByteArray::fromHex("011F"); QVERIFY(modbus.parseReadCoilsResponse(responseData, coils)); QCOMPARE(coils.size(), 5); // 验证线圈数量 for (int i = 0; i < 5; ++i) { QCOMPARE(coils[i], true); // 验证每个线圈状态为1 } // 测试用例 3: 字节数不匹配 // 数据格式: [字节数:02] [数据:03](数据长度与字节数声明不符) responseData = QByteArray::fromHex("0203"); QVERIFY(!modbus.parseReadCoilsResponse(responseData, coils)); // 测试用例 4: 空数据 responseData = QByteArray(); QVERIFY(!modbus.parseReadCoilsResponse(responseData, coils)); } // 测试 parseReadHoldingRegistersResponse 函数 void Test_Modbus::test_parseReadHoldingRegistersResponse() { ModbusRTUMaster modbus; QVector registers; // 测试用例 1: 正常读保持寄存器响应(2个寄存器) // 数据格式: [字节数:04] [数据:0001 0002] modbus.setRegCount(2); QByteArray responseData = QByteArray::fromHex("0400010002"); QVERIFY(modbus.parseReadHoldingRegistersResponse(responseData, registers)); QCOMPARE(registers.size(), 2); // 验证寄存器数量 QCOMPARE(registers[0], static_cast(0x0001)); // 验证寄存器1 QCOMPARE(registers[1], static_cast(0x0002)); // 验证寄存器2 // 测试用例 2: 读取10个寄存器 // 数据格式: [字节数:14] [数据:0001 0002 ... 000A] modbus.setRegCount(10); responseData = QByteArray::fromHex("14000100020003000400050006000700080009000A"); QVERIFY(modbus.parseReadHoldingRegistersResponse(responseData, registers)); QCOMPARE(registers.size(), 10); // 验证寄存器数量 for (int i = 0; i < 10; ++i) { QCOMPARE(registers[i], static_cast(i + 1)); // 验证每个寄存器值 } // 测试用例 3: 字节数不匹配 // 数据格式: [字节数:02] [数据:0001](数据长度与字节数声明不符) responseData = QByteArray::fromHex("020001"); QVERIFY(!modbus.parseReadHoldingRegistersResponse(responseData, registers)); // 测试用例 4: 空数据 responseData = QByteArray(); QVERIFY(!modbus.parseReadHoldingRegistersResponse(responseData, registers)); } QTEST_APPLESS_MAIN(Test_Modbus) #include "tst_test_modbus.moc"