كتابة عدّاء اختبار IRemoteTest مجزأ

عند كتابة تشغيل اختبار، من المهم التفكير في قابلية التوسيع والتطوير. طلب الانضمام "إذا اضطر عداء الاختبار إلى إجراء 200 ألف حالة اختبار" كم من الوقت سيستغرق؟

التقسيم إلى أجزاء هو إحدى الإجابات المتاحة في الاتحاد التجاري. يتطلب وتقسيم جميع الاختبارات التي يحتاجها العداء إلى عدة أجزاء يمكن بشكل موازٍ.

توضح هذه الصفحة كيفية جعل العداء قابلاً للتجزئة في 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 لا يجمّع نتائج اختبار للاستدعاءات المجزأة، يجب للتأكد من أن خدمة إعداد التقارير تتيح ذلك.