|
- #include <QtTest>
- #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<quint16> 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<quint8>(0x01)); // 验证从站地址
- QCOMPARE(funcCode, static_cast<quint8>(0x03)); // 验证功能码
- QCOMPARE(errorCode, ModbusRTUMaster::NO_ERROR); // 验证无错误
- QCOMPARE(parsedData.size(), 2); // 验证数据长度
- QCOMPARE(parsedData[0], static_cast<quint16>(0x0001)); // 验证寄存器1
- QCOMPARE(parsedData[1], static_cast<quint16>(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<quint8>(0x01)); // 验证从站地址
- QCOMPARE(funcCode, static_cast<quint8>(0x01)); // 验证功能码
- QCOMPARE(errorCode, ModbusRTUMaster::NO_ERROR); // 验证无错误
- QCOMPARE(parsedData.size(), 8); // 验证数据长度
- for (int i = 0; i < 8; ++i)
- {
- QCOMPARE(parsedData[i], static_cast<quint16>(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<quint8>(0x01)); // 验证从站地址
- QCOMPARE(funcCode, static_cast<quint8>(0x83)); // 验证功能码
- QCOMPARE(errorCode, static_cast<quint8>(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<bool> 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<quint16> 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<quint16>(0x0001)); // 验证寄存器1
- QCOMPARE(registers[1], static_cast<quint16>(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<quint16>(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"
|