在编写测试运行程序时,考虑可伸缩性很重要。问问自己,“如果我的测试运行程序必须运行 200K 测试用例”,需要多长时间?
分片是 Trade Federation 中可用的答案之一。它需要将运行器需要的所有测试分成几个可以并行化的块。
本页介绍如何使您的跑步者可用于 Tradefed。
实现接口
要实现被 TF 视为可分片的最重要的接口是IShardableTest ,它包含两个方法: split(int numShard)
和split()
。
如果您的分片将取决于请求的分片数量,您应该实现split(int numShard)
。否则,执行split()
。
当使用分片参数--shard-count
和--shard-index
执行 TF 测试命令时,TF 会遍历所有IRemoteTest
以查找实现IShardableTest
的那些。如果找到,它将调用split
来获取一个新的IRemoteTest
对象来运行特定分片的测试用例子集。
关于拆分实现,我应该知道什么?
- 您的跑步者只能在某些条件下进行分片;在这种情况下,当您没有分片时返回
null
。 - 尝试尽可能多地拆分:将您的跑步者拆分为对它有意义的执行单元。这真的取决于你的跑步者。例如: HostTest在 Class 级别进行分片,每个测试类都放在一个单独的分片中。
- 如果有意义,请添加一些选项来稍微控制分片。例如: AndroidJUnitTest有一个
ajur-max-shard
来指定它可以拆分的最大分片数,无论请求的数量是多少。
详细示例实现
这是一个实现IShardableTest
的示例代码片段,您可以参考。完整代码可在 (https://android.googlesource.com/platform/tools/tradefederation/+/refs/heads/master/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 不会对分片调用进行任何测试结果聚合,因此您需要确保您的报告服务支持它。