有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

具有不可预测的外部依赖项的java单元测试代码

我参与了一个项目,该项目必须控制各种实验室仪器(机器人、阅读器等)

这些仪器中的大多数是通过基于DCOM的驱动程序、串行端口或通过启动带有各种参数的专有程序来控制的。这些程序或驱动程序中有些包含模拟模式,有些不包含。显然,我的开发计算机无法连接到所有的仪器,虽然我可以为驱动程序包含模拟模式的仪器启动虚拟机,但如果没有实际的仪器,有些东西是无法测试的

现在,我自己的代码主要不是关于仪器的实际操作,而是关于开始操作,确保一切正常,并在它们之间同步。它是用Java编写的,使用各种库与仪器及其驱动程序进行接口

我想为各种仪表控制模块编写单元测试。然而,由于这些工具可能在许多方面失败(其中一些是有文档记录的,一些不是),因为代码依赖于这些部分随机的输出,所以对于如何为代码的这些部分编写单元测试,我有点不知所措。我考虑过以下解决办法:

  • 仅使用连接的实际仪器进行测试,这可能是最准确的方法,但根本不实用(在读卡器中插入板、运行单元测试、移除板、运行单元测试等),更不用说潜在的危险了
  • 使用模拟对象来模拟实际与对象通信的部分;虽然这一个显然更容易实现(和运行),但它可能无法再现所有潜在故障(如上所述,很多故障都没有记录,这有时会导致严重的意外)

虽然我目前正在考虑加入后者,但我是否遗漏了什么?有更好的方法吗


共 (3) 个答案

  1. # 1 楼答案

    如果使用模拟,则可以替换不同的模拟以执行不同的操作。也就是说,您的测试将是一致的。这很有价值,因为对随机执行的系统运行测试不会给您带来安全感。每次运行都可以/将执行不同的代码路径

    由于您事先不知道所有的故障场景,我认为有两种(非独占)场景:

    1. 捕获这些失败的详细信息,并在模拟中对进一步的测试进行编码,以复制这些失败。因此,您的日志记录需要可靠,以捕获故障详细信息。随着时间的推移,您的测试集将扩展到包含并回归测试这些场景
    2. 您与这些系统的接口可能能够捕获所有错误,但将它们呈现在有限的错误子集中。e、 g.将所有错误分类为(比如)连接错误、超时等。这样,您就可以将您的场景限制为一小部分故障。不幸的是,我不知道这是否适合你的应用
  2. # 2 楼答案

    两个要点都是有效的选项,但它们各自代表两种不同类型的测试

    在一个非常高的层次上,使用模拟对象(每一个要点)对于单元测试来说是非常好的,单元测试就是简单地测试您的代码(即被测试的系统,或者SUT),而没有其他无关的东西。任何其他依赖项都会被模拟出来。然后,您可以编写测试用例来抛出尽可能多的不同错误条件(当然也可以测试“快乐路径”)。不幸的是,您的错误条件域没有记录,您应该尽可能地减少这一点。每当您在实际的外部设备上遇到新的错误情况时,您都应该弄清楚如何通过代码再现它,然后编写另一个新的单元测试,以便通过模拟框架重新创建该情况

    此外,使用连接的实际工具进行测试(根据您的第一个要点)对于集成测试来说是非常好的,集成测试更多的是测试您的代码以及实际的外部依赖性

    一般来说,单元测试应该很快(理想情况下,编译代码和运行整个单元测试套件的时间不超过10分钟)这意味着,如果您编写的任何新代码导致任何测试失败,您将很快从单元测试中获得反馈。从本质上讲,集成测试可能需要更长的时间(例如,如果您的一个外部设备计算结果或执行任务需要1分钟,并且您有15组不同的输入正在测试,那么一个小测试套件就需要15分钟。)提交到源代码管理存储库时,应自动触发CI服务器(您应该有一个自动编译和运行所有测试的服务器)。它应该一步编译和运行单元测试。完成该部分后,它应该向您提供反馈(好的或坏的),然后如果单元测试全部通过,它应该自动启动您的集成测试。这假定存在连接到CI服务器的实际设备或合适的替换设备(无论在特定环境中意味着什么)

    希望有帮助

  3. # 3 楼答案

    根据定义,你不能对你没有预料到的东西进行单元测试

    第二种方法适用于单元测试。将实际仪器连接在一起,最多只能进行集成测试

    分离依赖项,这样您就可以创建一个伪仪器,然后尽可能多地使其模拟现实。当你对现实的理解提高时,更新你的假象并增加测试来应对这种情况。(在某些情况下,模仿可能是合适的,而在其他情况下,模仿可能是合适的。)