編寫測試執行程式時,請務必考量擴充性。請問自己:「如果測試執行程式必須執行 20 萬個測試案例,需要多久時間?」
分割是 Trade Federation 提供的答案之一。這項操作需要將執行程式需要的所有測試分割成可並行執行的多個區塊。
本頁說明如何讓執行程式可供 Tradefed 分割。
要實作的介面
如要讓 TF 將您的模型視為可分割,您必須實作最重要的介面 IShardableTest,其中包含 split(int numShard)
和 split()
這兩種方法。
如果區塊劃分作業取決於要求的區塊數量,您應實作 split(int numShard)
。否則,請實作 split()
。
當 TF 測試指令搭配使用區隔參數 --shard-count
和 --shard-index
執行時,TF 會逐一檢查所有 IRemoteTest
,尋找實作 IShardableTest
的 IRemoteTest
。如果找到,就會呼叫 split
取得新的 IRemoteTest
物件,為特定分割區執行部分測試案例。
請問我應該瞭解哪些關於分割導入方式的資訊?
- 您的執行程式只能在某些條件下分割;在這種情況下,如果您未分割,請傳回
null
。 - 盡可能分割:將執行程式分割成適當的執行單元。這取決於執行程式。例如:HostTest 是在類別層級進行分割,因此每個測試類別都會放入個別的分割區。
- 如果有需要,請新增一些選項來稍微控制分割作業。例如:AndroidJUnitTest 有
ajur-max-shard
,可指定可分割的切片數量上限,無論要求的數量為何。
詳細實作範例
以下是實作 IShardableTest
的程式碼片段範例,供您參考。完整程式碼可在 (https://android.googlesource.com/platform/tools/tradefederation/+/refs/heads/android16-release/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 不會為分割呼叫執行任何測試結果匯總作業,因此您必須確保報表服務支援這項作業。