เมื่อเขียน test runner สิ่งสำคัญคือต้องคำนึงถึงความสามารถในการขยายขนาด ถามตัวเองว่า "หากนักวิ่งทดสอบของฉันต้องทำกรณีทดสอบ 200,000 ครั้ง" จะใช้เวลานานเท่าใด
Sharding เป็นหนึ่งในคำตอบที่มีอยู่ใน Trade Federation โดยจะต้องแบ่งการทดสอบทั้งหมดที่นักวิ่งต้องการออกเป็นหลายๆ ส่วนซึ่งสามารถทำแบบขนานได้
หน้านี้อธิบายวิธีทำให้นักวิ่งของคุณสามารถเก็บชาร์ดได้สำหรับ Tradefed
อินเทอร์เฟซที่จะนำไปใช้
อินเทอร์เฟซเดียวที่สำคัญที่สุดที่จะนำไปใช้เพื่อให้ TF พิจารณาว่าสามารถแบ่งส่วนได้คือ IShardableTest ซึ่งมีสองวิธี: split(int numShard)
และ split()
หากการแบ่งส่วนของคุณจะขึ้นอยู่กับจำนวนชิ้นส่วนที่ร้องขอ คุณควรใช้ split(int numShard)
มิฉะนั้น ให้ใช้ split()
เมื่อคำสั่งทดสอบ TF ถูกดำเนินการด้วยพารามิเตอร์การแบ่ง --shard-count
และ --shard-index
TF จะวนซ้ำผ่าน IRemoteTest
ทั้งหมดเพื่อค้นหาคำสั่งที่ใช้งาน IShardableTest
หากพบ ระบบจะเรียก split
เพื่อรับออบเจ็กต์ IRemoteTest
ใหม่เพื่อรันชุดย่อยของกรณีทดสอบสำหรับส่วนแบ่งเฉพาะ
ฉันควรรู้อะไรบ้างเกี่ยวกับการใช้งานแบบแยกส่วน
- นักวิ่งของคุณอาจได้รับชิ้นส่วนตามเงื่อนไขบางประการเท่านั้น ในกรณีนั้นให้คืน
null
เมื่อคุณไม่ได้แยกส่วน - พยายามแบ่งให้มากที่สุดเท่าที่จะทำได้: แบ่งนักวิ่งของคุณออกเป็นหน่วยการดำเนินการที่เหมาะสม มันขึ้นอยู่กับนักวิ่งของคุณจริงๆ ตัวอย่างเช่น: HostTest ถูกแบ่งส่วนในระดับคลาส แต่ละคลาสการทดสอบจะถูกจัดแยกส่วน
- หากสมเหตุสมผล ให้เพิ่มตัวเลือกเพื่อควบคุมการแบ่งส่วนเล็กน้อย ตัวอย่างเช่น: 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 ไม่ได้รวมผลการทดสอบใดๆ สำหรับการเรียกใช้แบบแบ่งส่วน คุณจึงต้องแน่ใจว่าบริการการรายงานของคุณรองรับ