编写分片 IRemoteTest 测试运行程序,编写分片 IRemoteTest 测试运行程序,编写分片 IRemoteTest 测试运行程序,编写分片 IRemoteTest 测试运行程序

编写测试运行程序时,考虑可扩展性很重要。问问自己,“如果我的测试运行程序必须运行 20 万个测试用例”需要多长时间?

分片是 Trade Federation 中提供的答案之一。它需要将运行程序所需的所有测试分成几个可以并行化的块。

本页面介绍了如何使您的运行器可用于 Tradefed 分片。

要实现的接口

要实现 TF 认为可分片的最重要的一个接口是IShardableTest ,它包含两个方法: split(int numShard)split()

如果您的分片取决于请求的分片数量,您应该实现split(int numShard) 。否则,执行split()

当使用分片参数--shard-count--shard-index执行 TF 测试命令时,TF 会迭代所有IRemoteTest以查找实现IShardableTest的 IRemoteTest 。如果找到,它将调用split来获取新的IRemoteTest对象,以便为特定分片运行测试用例的子集。

关于拆分实施我应该了解哪些信息?

  • 您的跑步者只能在某些条件下进行分片;在这种情况下,当您没有分片时返回null
  • 尝试尽可能多地拆分:将运行程序拆分为对其有意义的执行单元。这实际上取决于您的跑步者。例如: HostTest在Class级别进行分片,每个测试类都放在一个单独的分片中。
  • 如果有意义的话,添加一些选项来稍微控制分片。例如: AndroidJUnitTest有一个ajur-max-shard来指定它可以分割的最大分片数量,无论请求的数量是多少。

详细示例实现

这是一个实现IShardableTest示例代码片段,您可以参考。完整代码可在(https://android.googlesource.com/platform/tools/tradefederation/+/refs/heads/main/test_framework/com/android/tradefed/testtype/InstalledInstrumentationsTest.java)获取

/**
 * Runs all instrumentation found on current device.
 */
@OptionClass(alias = "installed-instrumentation")
public class InstalledInstrumentationsTest
        implements IDeviceTest, IResumableTest, IShardableTest {
    ...

    /** {@inheritDoc} */
    @Override
    public Collection<IRemoteTest> split(int shardCountHint) {
        if (shardCountHint > 1) {
            Collection<IRemoteTest> shards = new ArrayList<>(shardCountHint);
            for (int index = 0; index < shardCountHint; index++) {
                shards.add(getTestShard(shardCountHint, index));
            }
            return shards;
        }
        // Nothing to shard
        return null;
    }

    private IRemoteTest getTestShard(int shardCount, int shardIndex) {
        InstalledInstrumentationsTest shard = new InstalledInstrumentationsTest();
        try {
            OptionCopier.copyOptions(this, shard);
        } catch (ConfigurationException e) {
            CLog.e("failed to copy instrumentation options: %s", e.getMessage());
        }
        shard.mShardIndex = shardIndex;
        shard.mTotalShards = shardCount;
        return shard;
    }
    ...
}

此示例只是创建其自身的新实例并为其设置分片参数。然而,不同测试的拆分逻辑可能完全不同;只要它是确定性的并且产生集体详尽的子集,就可以了。

独立

分片需要独立!在运行程序中实现split创建的两个分片不应相互依赖或共享资源。

分片分裂需要具有确定性!这也是强制性的,在相同的条件下,您的split方法应该始终以相同的顺序返回完全相同的分片列表。

注意:由于每个分片可以在不同的 TF 实例上运行,因此确保split逻辑产生互斥且以确定性方式集体详尽的子集至关重要。

在本地分片测试

要在本地 TF 上对测试进行分片,您只需将--shard-count选项添加到命令行即可。

tf >run host --class com.android.tradefed.UnitTests --shard-count 3

然后 TF 会自动为每个分片生成命令并运行它们。

tf >l i
Command Id  Exec Time  Device          State
3           0m:03      [null-device-2]  running stub on build 0 (shard 1 of 3)
3           0m:03      [null-device-1]  running stub on build 0 (shard 0 of 3)
3           0m:03      [null-device-3]  running stub on build 0 (shard 2 of 3)

测试结果汇总

由于 TF 不会对分片调用进行任何测试结果聚合,因此您需要确保您的报告服务支持它。

,

编写测试运行程序时,考虑可扩展性很重要。问问自己,“如果我的测试运行程序必须运行 20 万个测试用例”需要多长时间?

分片是 Trade Federation 中提供的答案之一。它需要将运行程序所需的所有测试分成几个可以并行化的块。

本页面介绍了如何使您的运行器可用于 Tradefed 分片。

要实现的接口

要实现 TF 认为可分片的最重要的一个接口是IShardableTest ,它包含两个方法: split(int numShard)split()

如果您的分片取决于请求的分片数量,您应该实现split(int numShard) 。否则,执行split()

当使用分片参数--shard-count--shard-index执行 TF 测试命令时,TF 会迭代所有IRemoteTest以查找实现IShardableTest的 IRemoteTest 。如果找到,它将调用split来获取新的IRemoteTest对象,以便为特定分片运行测试用例的子集。

关于拆分实施我应该了解哪些信息?

  • 您的跑步者只能在某些条件下进行分片;在这种情况下,当您没有分片时返回null
  • 尝试尽可能多地拆分:将运行程序拆分为对其有意义的执行单元。这实际上取决于您的跑步者。例如: HostTest在Class级别进行分片,每个测试类都放在一个单独的分片中。
  • 如果有意义的话,添加一些选项来稍微控制分片。例如: AndroidJUnitTest有一个ajur-max-shard来指定它可以分割的最大分片数量,无论请求的数量是多少。

详细示例实现

这是一个实现IShardableTest示例代码片段,您可以参考。完整代码可在(https://android.googlesource.com/platform/tools/tradefederation/+/refs/heads/main/test_framework/com/android/tradefed/testtype/InstalledInstrumentationsTest.java)获取

/**
 * Runs all instrumentation found on current device.
 */
@OptionClass(alias = "installed-instrumentation")
public class InstalledInstrumentationsTest
        implements IDeviceTest, IResumableTest, IShardableTest {
    ...

    /** {@inheritDoc} */
    @Override
    public Collection<IRemoteTest> split(int shardCountHint) {
        if (shardCountHint > 1) {
            Collection<IRemoteTest> shards = new ArrayList<>(shardCountHint);
            for (int index = 0; index < shardCountHint; index++) {
                shards.add(getTestShard(shardCountHint, index));
            }
            return shards;
        }
        // Nothing to shard
        return null;
    }

    private IRemoteTest getTestShard(int shardCount, int shardIndex) {
        InstalledInstrumentationsTest shard = new InstalledInstrumentationsTest();
        try {
            OptionCopier.copyOptions(this, shard);
        } catch (ConfigurationException e) {
            CLog.e("failed to copy instrumentation options: %s", e.getMessage());
        }
        shard.mShardIndex = shardIndex;
        shard.mTotalShards = shardCount;
        return shard;
    }
    ...
}

此示例只是创建其自身的新实例并为其设置分片参数。然而,不同测试的拆分逻辑可能完全不同;只要它是确定性的并且产生集体详尽的子集,就可以了。

独立

分片需要独立!在运行程序中实现split创建的两个分片不应相互依赖或共享资源。

分片分裂需要具有确定性!这也是强制性的,在相同的条件下,您的split方法应该始终以相同的顺序返回完全相同的分片列表。

注意:由于每个分片可以在不同的 TF 实例上运行,因此确保split逻辑产生互斥且以确定性方式集体详尽的子集至关重要。

在本地分片测试

要在本地 TF 上对测试进行分片,您只需将--shard-count选项添加到命令行即可。

tf >run host --class com.android.tradefed.UnitTests --shard-count 3

然后 TF 会自动为每个分片生成命令并运行它们。

tf >l i
Command Id  Exec Time  Device          State
3           0m:03      [null-device-2]  running stub on build 0 (shard 1 of 3)
3           0m:03      [null-device-1]  running stub on build 0 (shard 0 of 3)
3           0m:03      [null-device-3]  running stub on build 0 (shard 2 of 3)

测试结果汇总

由于 TF 不会对分片调用进行任何测试结果聚合,因此您需要确保您的报告服务支持它。

,

编写测试运行程序时,考虑可扩展性很重要。问问自己,“如果我的测试运行程序必须运行 20 万个测试用例”需要多长时间?

分片是 Trade Federation 中提供的答案之一。它需要将运行程序所需的所有测试分成几个可以并行化的块。

本页面介绍了如何使您的运行器可用于 Tradefed 分片。

要实现的接口

要实现 TF 认为可分片的最重要的一个接口是IShardableTest ,它包含两个方法: split(int numShard)split()

如果您的分片取决于请求的分片数量,您应该实现split(int numShard) 。否则,执行split()

当使用分片参数--shard-count--shard-index执行 TF 测试命令时,TF 会迭代所有IRemoteTest以查找实现IShardableTest的 IRemoteTest 。如果找到,它将调用split来获取新的IRemoteTest对象,以便为特定分片运行测试用例的子集。

关于拆分实施我应该了解哪些信息?

  • 您的跑步者只能在某些条件下进行分片;在这种情况下,当您没有分片时返回null
  • 尝试尽可能多地拆分:将运行程序拆分为对其有意义的执行单元。这实际上取决于您的跑步者。例如: HostTest在Class级别进行分片,每个测试类都放在一个单独的分片中。
  • 如果有意义的话,添加一些选项来稍微控制分片。例如: AndroidJUnitTest有一个ajur-max-shard来指定它可以分割的最大分片数量,无论请求的数量是多少。

详细示例实现

这是一个实现IShardableTest示例代码片段,您可以参考。完整代码可在(https://android.googlesource.com/platform/tools/tradefederation/+/refs/heads/main/test_framework/com/android/tradefed/testtype/InstalledInstrumentationsTest.java)获取

/**
 * Runs all instrumentation found on current device.
 */
@OptionClass(alias = "installed-instrumentation")
public class InstalledInstrumentationsTest
        implements IDeviceTest, IResumableTest, IShardableTest {
    ...

    /** {@inheritDoc} */
    @Override
    public Collection<IRemoteTest> split(int shardCountHint) {
        if (shardCountHint > 1) {
            Collection<IRemoteTest> shards = new ArrayList<>(shardCountHint);
            for (int index = 0; index < shardCountHint; index++) {
                shards.add(getTestShard(shardCountHint, index));
            }
            return shards;
        }
        // Nothing to shard
        return null;
    }

    private IRemoteTest getTestShard(int shardCount, int shardIndex) {
        InstalledInstrumentationsTest shard = new InstalledInstrumentationsTest();
        try {
            OptionCopier.copyOptions(this, shard);
        } catch (ConfigurationException e) {
            CLog.e("failed to copy instrumentation options: %s", e.getMessage());
        }
        shard.mShardIndex = shardIndex;
        shard.mTotalShards = shardCount;
        return shard;
    }
    ...
}

此示例只是创建其自身的新实例并为其设置分片参数。然而,不同测试的拆分逻辑可能完全不同;只要它是确定性的并且产生集体详尽的子集,就可以了。

独立

分片需要独立!在运行程序中实现split创建的两个分片不应相互依赖或共享资源。

分片分裂需要具有确定性!这也是强制性的,在相同的条件下,您的split方法应该始终以相同的顺序返回完全相同的分片列表。

注意:由于每个分片可以在不同的 TF 实例上运行,因此确保split逻辑产生互斥且以确定性方式集体详尽的子集至关重要。

在本地分片测试

要在本地 TF 上对测试进行分片,您只需将--shard-count选项添加到命令行即可。

tf >run host --class com.android.tradefed.UnitTests --shard-count 3

然后 TF 会自动为每个分片生成命令并运行它们。

tf >l i
Command Id  Exec Time  Device          State
3           0m:03      [null-device-2]  running stub on build 0 (shard 1 of 3)
3           0m:03      [null-device-1]  running stub on build 0 (shard 0 of 3)
3           0m:03      [null-device-3]  running stub on build 0 (shard 2 of 3)

测试结果汇总

由于 TF 不会对分片调用进行任何测试结果聚合,因此您需要确保您的报告服务支持它。

,

编写测试运行程序时,考虑可扩展性很重要。问问自己,“如果我的测试运行程序必须运行 20 万个测试用例”需要多长时间?

分片是 Trade Federation 中提供的答案之一。它需要将运行程序所需的所有测试分成几个可以并行化的块。

本页面介绍了如何使您的运行器可用于 Tradefed 分片。

要实现的接口

要实现 TF 认为可分片的最重要的一个接口是IShardableTest ,它包含两个方法: split(int numShard)split()

如果您的分片取决于请求的分片数量,您应该实现split(int numShard) 。否则,执行split()

当使用分片参数--shard-count--shard-index执行 TF 测试命令时,TF 会迭代所有IRemoteTest以查找实现IShardableTest的 IRemoteTest 。如果找到,它将调用split来获取新的IRemoteTest对象,以便为特定分片运行测试用例的子集。

关于拆分实施我应该了解哪些信息?

  • 您的跑步者只能在某些条件下进行分片;在这种情况下,当您没有分片时返回null
  • 尝试尽可能多地拆分:将运行程序拆分为对其有意义的执行单元。这实际上取决于您的跑步者。例如: HostTest在Class级别进行分片,每个测试类都放在一个单独的分片中。
  • 如果有意义的话,添加一些选项来稍微控制分片。例如: AndroidJUnitTest有一个ajur-max-shard来指定它可以分割的最大分片数量,无论请求的数量是多少。

详细示例实现

这是一个实现IShardableTest示例代码片段,您可以参考。完整代码可在(https://android.googlesource.com/platform/tools/tradefederation/+/refs/heads/main/test_framework/com/android/tradefed/testtype/InstalledInstrumentationsTest.java)获取

/**
 * Runs all instrumentation found on current device.
 */
@OptionClass(alias = "installed-instrumentation")
public class InstalledInstrumentationsTest
        implements IDeviceTest, IResumableTest, IShardableTest {
    ...

    /** {@inheritDoc} */
    @Override
    public Collection<IRemoteTest> split(int shardCountHint) {
        if (shardCountHint > 1) {
            Collection<IRemoteTest> shards = new ArrayList<>(shardCountHint);
            for (int index = 0; index < shardCountHint; index++) {
                shards.add(getTestShard(shardCountHint, index));
            }
            return shards;
        }
        // Nothing to shard
        return null;
    }

    private IRemoteTest getTestShard(int shardCount, int shardIndex) {
        InstalledInstrumentationsTest shard = new InstalledInstrumentationsTest();
        try {
            OptionCopier.copyOptions(this, shard);
        } catch (ConfigurationException e) {
            CLog.e("failed to copy instrumentation options: %s", e.getMessage());
        }
        shard.mShardIndex = shardIndex;
        shard.mTotalShards = shardCount;
        return shard;
    }
    ...
}

此示例只是创建其自身的新实例并为其设置分片参数。然而,不同测试的拆分逻辑可能完全不同;只要它是确定性的并且产生集体详尽的子集,就可以了。

独立

分片需要独立!在运行程序中实现split创建的两个分片不应相互依赖或共享资源。

分片分裂需要具有确定性!这也是强制性的,在相同的条件下,您的split方法应该始终以相同的顺序返回完全相同的分片列表。

注意:由于每个分片可以在不同的 TF 实例上运行,因此确保split逻辑产生互斥且以确定性方式集体详尽的子集至关重要。

在本地分片测试

要在本地 TF 上对测试进行分片,您只需将--shard-count选项添加到命令行即可。

tf >run host --class com.android.tradefed.UnitTests --shard-count 3

然后 TF 会自动为每个分片生成命令并运行它们。

tf >l i
Command Id  Exec Time  Device          State
3           0m:03      [null-device-2]  running stub on build 0 (shard 1 of 3)
3           0m:03      [null-device-1]  running stub on build 0 (shard 0 of 3)
3           0m:03      [null-device-3]  running stub on build 0 (shard 2 of 3)

测试结果汇总

由于 TF 不会对分片调用进行任何测试结果聚合,因此您需要确保您的报告服务支持它。