教程

测试序列化器和解析器

qianmoQqianmoQ· 更新于 2026-10-01· 阅读 6 分钟· 0 次阅读

登录后可跨设备保存划线和私人笔记登录

目前,构建过程会根据提供的 mspec 规范生成序列化器和解析器。

针对模型、解析器和序列化器的一次典型完整往返测试如下所示:

  • 从一个字节数组开始
  • 使用解析器解析该字节数组
  • 将解析得到的模型实例与预期模型进行比较
  • 如果预期模型与之匹配,则将该模型序列化回字节数组
  • 将得到的字节数组与原始字节数组进行比较
  • 如果两个字节数组完全一致,则认为此次往返测试通过

手动执行这些操作需要大量的对象构造和验证工作,因此我们创建了一个用于编写此类测试的框架。

XML 无论你对它看法如何,都能够提供简单且易于阅读的描述,因此这些测试以 XML files 的形式提供。

所有生成的模型类都支持通过 Jackson 进行 XML 的解析与序列化。

测试的结构

一个典型的测试如下所示:

  <testcase>
    <name>Read Input Registers Request</name>
    <raw>000000000006ff0408d20002</raw>
    <root-type>ModbusTcpADU</root-type>
    <parser-arguments>
      <response>false</response>
    </parser-arguments>
    <xml>
      <ModbusTcpADU className="org.apache.plc4x.java.modbus.readwrite.ModbusTcpADU">
        <transactionIdentifier>0</transactionIdentifier>
        <unitIdentifier>255</unitIdentifier>
        <pdu className="org.apache.plc4x.java.modbus.readwrite.ModbusPDUReadInputRegistersRequest">
          <startingAddress>2258</startingAddress>
          <quantity>2</quantity>
        </pdu>
      </ModbusTcpADU>
    </xml>
  </testcase>

可以看出,name 为该测试提供了一个简单易读的名称,用于报告测试的成功或失败。

raw 元素包含该 binary input 的 hex-representation。

随后,root-type 指定了用于解析该数据的基础类型。在上面的示例中,测试将使用 ModbusTcpADUIO.serialize 和 ModbusTcpADUIO.parse 方法进行序列化和解析。

某些解析器在解析时需要额外的参数。在上面的示例中,Modbus 协议无法仅凭数据本身判断其是请求还是响应,因此我们必须通过 parser-arguments 参数传入该信息。

最后一个元素是 xml 元素,其中包含被解析对象的 XML 表示。

每个测试都严格实现上述测试策略,不过在比较解析结果与期望模型时,我们使用 XMLUint 将解析得到的模型序列化为 XML,并将其与测试用例声明中给出的 XML 进行比较。

测试套件的结构

多个测试通常被封装在一个测试套件文档中。

总体而言,这只是一个带有指定测试套件 name 以及若干 testcase 元素的容器。

不过,有一个重要的设置用于控制协议的字节序。

该设置由测试套件根元素中的 bigEndian 属性控制。

一个测试套件文档的示例如下:

<?xml version="1.0" encoding="UTF-8"?>
<test:testsuite xmlns:test="https://plc4x.apache.org/schemas/parser-serializer-testsuite.xsd"
                bigEndian="true">

  <name>Allen-Bradley DF1</name>

  <testcase>
    ...
  </testcase>

  <testcase>
    ...
  </testcase>

  <testcase>
    ...
  </testcase>

  <testcase>
    ...
  </testcase>

</test:testsuite>

Junit 运行器

所有逻辑均在 plc4j-utils-test-utils 模块中实现,因此请确保添加以下测试依赖:

    <dependency>
      <groupId>org.apache.plc4x</groupId>
      <artifactId>plc4j-utils-test-utils</artifactId>
      <version>{project.version}</version>
      <scope>test</scope>
    </dependency>

为了在构建过程中运行这些测试,作为最后一步,我们需要创建一个测试运行器类。

这通常只是一些样板代码,用于告诉测试该使用哪个文档进行测试。

下面的代码片段对于每个测试套件来说基本都是一样的:

package org.apache.plc4x.java.modbus;

import org.apache.plc4x.test.parserserializer.ParserSerializerTestsuiteRunner;

public class ModbusIOTest extends ParserSerializerTestsuiteRunner {

    public ModbusIOTest() {
        super("/testsuite/ModbusTestsuite.xml");
    }

}

此处文档 ModbusTestsuite.xml 位于目录 src/test/resources/testsuite/ 中。

评论

登录后参与评论

正在加载评论…