You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

166 line
6.7 KiB

  1. #include <QtTest>
  2. #include "../ModbusMatser/modbus_master.h"
  3. // 单元测试类,用于测试 ModbusRTUMaster 类的解析函数
  4. class Test_Modbus : public QObject
  5. {
  6. Q_OBJECT
  7. public:
  8. Test_Modbus();
  9. ~Test_Modbus();
  10. private slots:
  11. // 测试用例声明
  12. void test_parseResponse(); // 测试 parseResponse 函数
  13. void test_parseReadCoilsResponse(); // 测试 parseReadCoilsResponse 函数
  14. void test_parseReadHoldingRegistersResponse(); // 测试 parseReadHoldingRegistersResponse 函数
  15. };
  16. // 构造函数
  17. Test_Modbus::Test_Modbus()
  18. {
  19. }
  20. // 析构函数
  21. Test_Modbus::~Test_Modbus()
  22. {
  23. }
  24. // 测试 parseResponse 函数
  25. void Test_Modbus::test_parseResponse()
  26. {
  27. ModbusRTUMaster modbus;
  28. quint8 slaveAddr, funcCode, errorCode;
  29. QVector<quint16> parsedData;
  30. // 测试用例 1: 正常读保持寄存器响应(功能码03,2个寄存器)
  31. // 帧格式: [从站地址:01] [功能码:03] [字节数:04] [数据:0001 0003] [CRC]
  32. QByteArray response = QByteArray::fromHex("01030400010003EBF2");
  33. modbus.setRegCount(2); // 设置期望的寄存器数量
  34. QVERIFY(modbus.parseResponse(response, slaveAddr, funcCode, parsedData, errorCode));
  35. QCOMPARE(slaveAddr, static_cast<quint8>(0x01)); // 验证从站地址
  36. QCOMPARE(funcCode, static_cast<quint8>(0x03)); // 验证功能码
  37. QCOMPARE(errorCode, ModbusRTUMaster::NO_ERROR); // 验证无错误
  38. QCOMPARE(parsedData.size(), 2); // 验证数据长度
  39. QCOMPARE(parsedData[0], static_cast<quint16>(0x0001)); // 验证寄存器1
  40. QCOMPARE(parsedData[1], static_cast<quint16>(0x0003)); // 验证寄存器3
  41. // 测试用例 2: 正常读线圈响应(功能码01,8个线圈)
  42. // 帧格式: [从站地址:01] [功能码:01] [字节数:01] [数据:FF] [CRC]
  43. modbus.setCoilCount(8); // 设置期望的线圈数量
  44. response = QByteArray::fromHex("010101FF11C8");
  45. QVERIFY(modbus.parseResponse(response, slaveAddr, funcCode, parsedData, errorCode));
  46. QCOMPARE(slaveAddr, static_cast<quint8>(0x01)); // 验证从站地址
  47. QCOMPARE(funcCode, static_cast<quint8>(0x01)); // 验证功能码
  48. QCOMPARE(errorCode, ModbusRTUMaster::NO_ERROR); // 验证无错误
  49. QCOMPARE(parsedData.size(), 8); // 验证数据长度
  50. for (int i = 0; i < 8; ++i)
  51. {
  52. QCOMPARE(parsedData[i], static_cast<quint16>(1)); // 验证所有线圈为1
  53. }
  54. // 测试用例 3: 错误响应(功能码83,非法功能)
  55. // 帧格式: [从站地址:01] [功能码:83] [错误码:01] [CRC]
  56. parsedData.clear();
  57. response = QByteArray::fromHex("01830180F0");
  58. QVERIFY(modbus.parseResponse(response, slaveAddr, funcCode, parsedData, errorCode));
  59. QCOMPARE(slaveAddr, static_cast<quint8>(0x01)); // 验证从站地址
  60. QCOMPARE(funcCode, static_cast<quint8>(0x83)); // 验证功能码
  61. QCOMPARE(errorCode, static_cast<quint8>(0x01)); // 验证错误码
  62. QCOMPARE(parsedData.size(), 0); // 验证无数据
  63. // 测试用例 4: 数据帧过短(无效帧)
  64. response = QByteArray::fromHex("0103"); // 只有2字节,少于最小长度
  65. QVERIFY(!modbus.parseResponse(response, slaveAddr, funcCode, parsedData, errorCode));
  66. // 测试用例 5: CRC错误
  67. // 帧格式: [从站地址:01] [功能码:03] [字节数:04] [数据:0001 0004] [错误CRC]
  68. response = QByteArray::fromHex("01030400010004AB30");
  69. QVERIFY(!modbus.parseResponse(response, slaveAddr, funcCode, parsedData, errorCode));
  70. // 测试用例 6: 不支持的功能码
  71. // 帧格式: [从站地址:01] [功能码:05] [数据] [CRC]
  72. response = QByteArray::fromHex("01050400010002D6E9");
  73. QVERIFY(!modbus.parseResponse(response, slaveAddr, funcCode, parsedData, errorCode));
  74. }
  75. // 测试 parseReadCoilsResponse 函数
  76. void Test_Modbus::test_parseReadCoilsResponse()
  77. {
  78. ModbusRTUMaster modbus;
  79. QVector<bool> coils;
  80. // 测试用例 1: 正常读线圈响应(8个线圈全1)
  81. // 数据格式: [字节数:01] [数据:FF]
  82. modbus.setCoilCount(8);
  83. QByteArray responseData = QByteArray::fromHex("01FF");
  84. QVERIFY(modbus.parseReadCoilsResponse(responseData, coils));
  85. QCOMPARE(coils.size(), 8); // 验证线圈数量
  86. for (int i = 0; i < 8; ++i)
  87. {
  88. QCOMPARE(coils[i], true); // 验证每个线圈状态为1
  89. }
  90. // 测试用例 2: 正常读线圈响应(5个线圈,前5位为1)
  91. // 数据格式: [字节数:01] [数据:1F]
  92. modbus.setCoilCount(5);
  93. responseData = QByteArray::fromHex("011F");
  94. QVERIFY(modbus.parseReadCoilsResponse(responseData, coils));
  95. QCOMPARE(coils.size(), 5); // 验证线圈数量
  96. for (int i = 0; i < 5; ++i)
  97. {
  98. QCOMPARE(coils[i], true); // 验证每个线圈状态为1
  99. }
  100. // 测试用例 3: 字节数不匹配
  101. // 数据格式: [字节数:02] [数据:03](数据长度与字节数声明不符)
  102. responseData = QByteArray::fromHex("0203");
  103. QVERIFY(!modbus.parseReadCoilsResponse(responseData, coils));
  104. // 测试用例 4: 空数据
  105. responseData = QByteArray();
  106. QVERIFY(!modbus.parseReadCoilsResponse(responseData, coils));
  107. }
  108. // 测试 parseReadHoldingRegistersResponse 函数
  109. void Test_Modbus::test_parseReadHoldingRegistersResponse()
  110. {
  111. ModbusRTUMaster modbus;
  112. QVector<quint16> registers;
  113. // 测试用例 1: 正常读保持寄存器响应(2个寄存器)
  114. // 数据格式: [字节数:04] [数据:0001 0002]
  115. modbus.setRegCount(2);
  116. QByteArray responseData = QByteArray::fromHex("0400010002");
  117. QVERIFY(modbus.parseReadHoldingRegistersResponse(responseData, registers));
  118. QCOMPARE(registers.size(), 2); // 验证寄存器数量
  119. QCOMPARE(registers[0], static_cast<quint16>(0x0001)); // 验证寄存器1
  120. QCOMPARE(registers[1], static_cast<quint16>(0x0002)); // 验证寄存器2
  121. // 测试用例 2: 读取10个寄存器
  122. // 数据格式: [字节数:14] [数据:0001 0002 ... 000A]
  123. modbus.setRegCount(10);
  124. responseData = QByteArray::fromHex("14000100020003000400050006000700080009000A");
  125. QVERIFY(modbus.parseReadHoldingRegistersResponse(responseData, registers));
  126. QCOMPARE(registers.size(), 10); // 验证寄存器数量
  127. for (int i = 0; i < 10; ++i)
  128. {
  129. QCOMPARE(registers[i], static_cast<quint16>(i + 1)); // 验证每个寄存器值
  130. }
  131. // 测试用例 3: 字节数不匹配
  132. // 数据格式: [字节数:02] [数据:0001](数据长度与字节数声明不符)
  133. responseData = QByteArray::fromHex("020001");
  134. QVERIFY(!modbus.parseReadHoldingRegistersResponse(responseData, registers));
  135. // 测试用例 4: 空数据
  136. responseData = QByteArray();
  137. QVERIFY(!modbus.parseReadHoldingRegistersResponse(responseData, registers));
  138. }
  139. QTEST_APPLESS_MAIN(Test_Modbus)
  140. #include "tst_test_modbus.moc"