عند كتابة أداة لتشغيل الاختبارات، من المهم التفكير في قابلية التوسّع. اسأل نفسك، "إذا كان على أداة تشغيل الاختبار تنفيذ 200 ألف حالة اختبار"، كم من الوقت سيستغرق ذلك؟
التجزئة هي إحدى الإجابات المتاحة في 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
في أداة التشغيل أو أن تشتركا في
الموارد.
يجب أن يكون تقسيم الشرائح حتميًا. هذا الإجراء إلزامي أيضًا، فوفقًا لل conditions نفسها، يجب أن تُرجع طريقة split
دائمًا القائمة نفسها بالfragments بالترتيب نفسه.
ملاحظة: بما أنّه يمكن تشغيل كل جزء على مثيلات 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 لا تُجري أي تجميع لنتائج الاختبار لطلبات التنفيذ المقسّمة، عليك التأكّد من أنّ خدمة إعداد التقارير تتيح ذلك.