编写 Tradefed 测试运行程序

本页面介绍了如何在 Tradefed 中编写新的测试运行程序。

背景

如果您对测试运行程序在 Tradefed 架构中的位置感到好奇,请参阅测试运行程序的结构

这不是编写新测试运行程序的先决条件;测试运行程序可以独立编写。

最低要求:实现接口

符合 Tradefed 测试运行程序资格的最低要求是实现 IRemoteTest 接口,更具体地说是实现 run(TestInformation testInfo, ITestInvocationListener listener) 方法。

此方法是在使用测试运行程序时由框架调用的方法,类似于 Java Runnable。

该方法的每个部分都被视为测试运行程序执行的一部分。

从测试运行程序报告结果

基本接口中的 run 方法允许访问类型为 ITestInvocationListener 的监听器对象。此对象是将结构化结果从测试运行程序报告给 harness 的关键。

通过报告结构化结果,测试运行程序具有以下属性:

  • 报告已运行的所有测试的正确列表,包括它们所花费的时间以及它们是单独通过、失败还是处于其他状态。
  • 如果适用,报告与测试相关的指标,例如安装时间指标。
  • 适应大多数基础设施工具,例如显示结果和指标等。
  • 通常更容易调试,因为执行过程有更精细的跟踪。

话虽如此,报告结构化结果是可选的;测试运行程序可能只想评估整个运行的状态为“通过”或“失败”,而无需实际执行的任何详细信息。

可以在监听器上调用以下事件,以将执行的当前进度通知 harness:

  • testRunStarted:通知相关的一组测试用例的开始。
    • testStarted:通知测试用例开始。
    • testFailed/testIgnored:通知正在进行的测试用例的状态更改。没有任何状态更改的测试用例被视为通过。
    • testEnded:通知测试用例的结束。
  • testRunFailed:通知一组测试用例执行的总体状态为失败。测试运行可以是通过失败独立于测试用例结果,具体取决于执行的预期结果。例如,运行多个测试用例的二进制文件可能会报告所有通过的测试用例,但退出代码错误(由于任何原因:文件泄漏等)。
  • testRunEnded:通知一组测试用例的结束。

维护和确保回调的正确顺序是测试运行程序实施者的责任,例如,确保在使用 finally 子句的情况下调用 testRunEnded

测试用例回调(testStartedtestEnded 等)是可选的。测试运行可能在没有任何测试用例的情况下发生。

您可能会注意到,这种事件结构的灵感来自 典型的 JUnit 结构。这是故意的,目的是使其接近开发人员通常了解的基础知识。

报告来自测试运行程序的日志

如果您要编写自己的 Tradefed 测试类或运行程序,您将实现 IRemoteTest 并通过 run() 方法获取 ITestInvocationListener。此监听器可用于记录文件,如下所示:

    listener.testLog(String dataName, LogDataType type_of_data, InputStreamSource data);

使用设备进行测试

上面的最小接口允许运行非常简单的、隔离的且不需要任何特定资源的测试,例如 Java 单元测试。

想要进行下一步设备测试的测试编写者将需要以下接口:

  • IDeviceTest 允许接收代表被测设备的 ITestDevice 对象,并提供与其交互的 API。
  • IBuildReceiver 允许测试获取在 构建提供程序步骤 创建的 IBuildInfo 对象,其中包含与测试设置相关的所有信息和工件。

测试运行程序通常对这些接口感兴趣,以便获取与执行相关的工件(例如,额外的文件)并获取将在执行期间作为目标的被测设备。

使用多个设备进行测试

Tradefed 支持同时在多个设备上运行测试。当测试需要外部交互的组件(如手机和手表配对)时,这非常有用。

为了编写可以使用多个设备的测试运行程序,您需要实现 IMultiDeviceTest,这将允许接收 ITestDeviceIBuildInfo 的映射,其中包含设备表示及其关联的构建信息的完整列表。

接口中的 setter 将始终在 run 方法之前调用,因此可以安全地假设当调用 run 时,该结构将可用。

了解其设置的测试

某些测试运行程序实现可能需要有关整体设置的信息才能正常工作,例如有关调用的某些元数据,或者之前运行了哪个 target_preparer 等。

为了实现这一点,测试运行程序可以访问它所属并在其中执行的 IConfiguration 对象。有关更多详细信息,请参阅 配置对象 描述。

对于测试运行程序实现,您将需要实现 IConfigurationReceiver 以接收 IConfiguration 对象。

灵活的测试运行程序

如果测试运行程序可以对其测试进行精细控制,例如 JUnit 测试运行程序可以单独运行每个单元测试,则它们可以提供一种灵活的测试运行方式。

这允许更大的 harness 和基础架构利用这种精细控制,并允许用户通过过滤部分运行测试运行程序。

过滤支持在 ITestFilterReceiver 接口 中描述,该接口允许接收应该运行或不应该运行的测试的 includeexclude 过滤器集。

我们的约定是,当且仅当测试匹配一个或多个包含过滤器并且不匹配任何排除过滤器时,测试才会运行。如果未给出包含过滤器,则应运行所有测试,只要它们不匹配任何排除过滤器即可。