如何报告 Tradefed 测试中的指标或数据

本页介绍在 Tradefed 中编写测试时如何报告指标以及测试结果。

通过 Tradefed 管道进行日志记录的好处是您可以在函数式结果旁边找到相应指标。指标的记录可以在测试中非常自然地完成,这便于测试编写者添加更多插桩测试。

DeviceTestCase - JUnit3 型测试

如果您的测试在 JUnit3 型测试中扩展 DeviceTestCase,那么您可以从任何测试用例内调用 addTestMetric(String key, String value) 方法来报告指标。只要键是唯一的,就可以多次调用此方法。

示例:

    public static class TestMetricTestCase extends DeviceTestCase {

        public void testPass() {
            addTestMetric("key1", "metric1");
        }

        public void testPass2() {
            addTestMetric("key2", "metric2");
        }
    }

如果您要记录在 result_reporters 中可用的文件,那么您可以从任何测试用例内调用 addTestLog(String dataName, LogDataType dataType, InputStreamSource dataStream) 方法来报告要记录的文件。

示例:

    public static class TestLogTestCase extends DeviceTestCase {

        public void testPass() {
            try (InputStreamSource source = getDevice().getScreenshot()) {
                addTestLog("screenshot", LogDataType.PNG, source);
            }
        }
    }

TestCase - 常规 JUnit3 测试

如果您要通过某个常规 JUnit3 TestCase 类报告 Tradefed 内的指标,那么需要将该类转换为 MetricTestCase,它与 TestCase 类完全相同,只不过包含一种额外的方法:addTestMetric(String key, String value)

DeviceJUnit4ClassRunner - JUnit4 型测试

如果您使用 DeviceJUnit4ClassRunner 来运行 JUnit4 型测试,那么您还可以记录测试用例中(在 @Test 内)要由 Tradefed 报告的指标。您需要使用 TestMetrics 规则来报告相应指标。

示例:

    @RunWith(DeviceJUnit4ClassRunner.class)
    public static class Junit4TestClass {

        @Rule
        public TestMetrics metrics = new TestMetrics();

        @Test
        public void testPass5() {
            // test log through the rule.
            metrics.addTestMetric("key", "value");
        }

        @Test
        public void testPass6() {
            metrics.addTestMetric("key2", "value2");
        }
    }

要报告文件,您应使用 TestLogData 规则来报告。

示例:

    @RunWith(DeviceJUnit4ClassRunner.class)
    public static class Junit4TestClass {

        @Rule
        public TestLogData logs = new TestLogData();

        @Test
        public void testPass5() {
            // test log through the rule.
            try (InputStreamSource source = getDevice().getScreenshot()) {
                logs.addTestLog("screenshot", LogDataType.PNG, source);
            }
        }
    }

IRemoteTest - 纯 Tradefed 测试

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

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

Tradefed 指标收集器

Tradefed 提供了一个专用的 metrics_collector 对象,用于在运行测试的同时收集指标。

在主机端

可以实现 BaseDeviceMetricCollector 以从主机端收集任意指标,并在测试调用过程中报告这些指标。许多通用收集器已经可用于不同的用例,但我们总是欢迎您做出新的贡献。

要指定要在 Tradefed 调用过程中使用的收集器,您只需将该对象添加到 Tradefed XML 配置:

示例:

  <metrics_collector class="com.android.tradefed.device.metric.AtraceCollector">
      <option name="categories" value="freq"/>
  </metrics_collector>

下面是一些现有的收集器: * TemperatureCollector 在测试运行期间定期收集温度。 * AtraceCollector 针对每个测试用例收集“atrace”的使用指标。

在设备端

在运行设备端测试(插桩测试、UIAutomator 测试等)时,让主机端的收集器异步收集指标可能并不是理想的做法。例如,异步截取的屏幕截图很可能会错过想要的屏幕,变得毫无用处。

为了满足这些用例的要求,我们提供了收集器的设备端版本,该版本可用于任何“AndroidJUnitRunner”插桩测试。 可以实现 BaseMetricListener,以便自动报告采用与 Tradefed 报告渠道完全兼容的方式收集的指标。

如果您使用的是 Tradefed 的“AndroidJUnitTest”运行程序,那么您可以直接指定以下命令行选项,让您的收集器与测试一起运行:

  --device-listeners android.device.collectors.ScreenshotListener

注意:为了能够在运行时解析收集器类,您的插桩测试 APK 很可能需要静态地包含这些类。为此,您可以将以下内容添加到 makefile:

  LOCAL_STATIC_JAVA_LIBRARIES += collector-device-lib

我们也欢迎您对设备端收集器做出贡献。

对套件的特别考虑

在部分套件(如 CTS)中,顶级配置运行一些模块配置,对于此类套件,不需要在每个模块配置 (AndroidTest.xml) 中指定 metrics_collector。实际上禁止这样做。

要确保指标收集同样地应用于每个模块,只有顶级配置(例如 cts.xml)可以指定 metrics_collector,如上所述。这些收集器将针对套件的每个模块应用并运行。

如何从模块收集设备日志文件?

为使设备端测试能够通知应收集某些文件,我们提供了相应设置。

AndroidTest.xml 可以指定一个收集器,该收集器将在设备上查找文件并提取这些文件。

  <metrics_collector class="com.android.tradefed.device.metric.FilePullerLogCollector">
      <!-- repeatable: Pattern of key of a FILE we listen on that should be pulled -->
      <option name = "pull-pattern-keys" value = "ScreenshotListener_.*" />

      <!-- repeatable: The key of the DIRECTORY to pull -->
      <option name = "directory-keys" value = "<example-key: /sdcard/atrace_logs>" />
  </metrics_collector>

指定这些模式和键后,如果收集器发现相应键,将尝试提取并记录关联的文件。

为了生成这些键,设备端测试(插桩测试)应该指定应记录的文件。它的完成方式与主机端测试(如上所述)类似。

  1. collector-device-lib 添加到 makefile 中的测试 APK:
  LOCAL_STATIC_JAVA_LIBRARIES += collector-device-lib
  1. 使用我们提供的 @rule 来记录文件:
    @RunWith(AndroidJUnit4.class)
    public static class Junit4TestClass {

        @Rule
        public TestLogData logs = new TestLogData();

        @Test
        public void testPass5() {
            // test log through the rule.
            File logFile = new File("whatever");
            logs.addTestLog("KEY", logFile);
        }
    }

上例中的 KEY 名称是报告文件时将会使用的名称。您应在 FilePullerDeviceMetricCollector 中匹配此名称,以自动提取相应文件。它应该是一个唯一的名称。

注意:提取文件后,FilePullerDeviceMetricCollector 会自动将其从设备中清除。

在哪里可以找到指标?

这取决于在 XML 配置中指定的 result_reporter