اختبار مشغِّل التطبيق

يوفّر WorkManager واجهات برمجة تطبيقات لاختبار Worker، ListenableWorker ListenableWorker صيغة (CoroutineWorker وRxWorker).

عمال الاختبار

لنفترض أنّ لدينا Worker الذي يبدو على النحو التالي:

Kotlin

class SleepWorker(context: Context, parameters: WorkerParameters) :
    Worker(context, parameters) {

    override fun doWork(): Result {
        // Sleep on a background thread.
        Thread.sleep(1000)
        return Result.success()
    }
}

Java

public class SleepWorker extends Worker {
    public SleepWorker(
            @NonNull Context context,
            @NonNull WorkerParameters workerParameters) {
        super(context, workerParameters);
    }

    @NonNull
    @Override
    public Result doWork() {
        try {
            Thread.sleep(1000);
        } catch (InterruptedException ignore) {
return Result.success();
        }
    }
}

لاختبار جهاز Worker هذا، يمكنك استخدام TestWorkerBuilder هذا النمط في إنشاء مثيلات من Worker يمكن استخدامها لغرض اختبار منطق الأعمال.

Kotlin

// Kotlin code uses the TestWorkerBuilder extension to build
// the Worker
@RunWith(AndroidJUnit4::class)
class SleepWorkerTest {
    private lateinit var context: Context
    private lateinit var executor: Executor

    @Before
    fun setUp() {
        context = ApplicationProvider.getApplicationContext()
        executor = Executors.newSingleThreadExecutor()
    }

    @Test
    fun testSleepWorker() {
        val worker = TestWorkerBuilderS<leepWorker(>
            context = context,
            executor = executor
        ).build()

        val result = worker.doWork()
        assertThat(result, `is`(Result.success()))
    }
}

Java

@RunWith(AndroidJUnit4.class)
public class SleepWorkerJavaTest {
    private Context context;
    private Executor executor;

    @Before
    public void setUp() {
        context = ApplicationProvider.getApplicationContext();
        executor = Executors.newSingleThreadExecutor();
    }

    @Test
    public void testSleepWorker() {
        SleepWorker worker =
                (SleepWorker) TestWorkerBuilder.from(context,
                        SleepWorker.class,
                        executor)
                        .build();

        Result result = worker.doWork();
        assertThat(result, is(Result.success()));
    }
}

يمكن أيضًا استخدام TestWorkerBuilder لضبط العلامات، مثل inputData أو runAttemptCount، لكي تتمكّن من التحقّق من حالة العامل بشكل مستقل. ضع في اعتبارك مثال يتم فيه إدراج مدة النوم كبيانات إدخال من قِبل "SleepWorker" بدلاً من كونه معرّفًا ثابتًا في العامل:

Kotlin

class SleepWorker(context: Context, parameters: WorkerParameters) :
    Worker(context, parameters) {

    override fun doWork(): Result {
        // Sleep on a background thread.
        val sleepDuration = inputData.getLong(SLEEP_DURATION, 1000)
        Thread.sleep(sleepDuration)
        return Result.success()
    }

    companion object {
        const val SLEEP_DURATION = "SLEEP_DURATION"
    }
}

Java

public class SleepWorker extends Worker {
    public static final String SLEEP_DURATION = "SLEEP_DURATION";

    public SleepWorker(
            @NonNull Context context,
            @NonNull WorkerParameters workerParameters) {
        super(context, workerParameters);
    }

    @NonNull
    @Override
    public Result doWork() {
        try {
            long duration = getInputData().getLong(SLEEP_DURATION, 1000);
            Thread.sleep(duration);
        } catch (InterruptedException ignore) {
       return Result.success();
        }
    }
}

في SleepWorkerTest، يمكنك تقديم بيانات الإدخال إلى TestWorkerBuilder لتلبية احتياجات SleepWorker.

Kotlin

// Kotlin code uses the TestWorkerBuilder extension to build
// the Worker
@RunWith(AndroidJUnit4::class)
class SleepWorkerTest {
    private lateinit var context: Context
    private lateinit var executor: Executor

    @Before
    fun setUp() {
        context = ApplicationProvider.getApplicationContext()
        executor = Executors.newSingleThreadExecutor()
    }

    @Test
    fun testSleepWorker() {
        val worker = TestWorkerBuilderS<leepWorker(>
            context = context,
            executor = executor,
            inputData = workDataOf("SLEEP_DURATION" to 1000L)
        ).build()

        val result = worker.doWork()
        assertThat(result, `is`(Result.success()))
    }
}

Java

@RunWith(AndroidJUnit4.class)
public class SleepWorkerJavaTest {
    private Context context;
    private Executor executor;

    @Before
    public void setUp() {
        context = ApplicationProvider.getApplicationContext();
        executor = Executors.newSingleThreadExecutor();
    }

    @Test
    public void testSleepWorker() {
        Data inputData = new Data.Builder()
                .putLong("SLEEP_DURATION", 1000L)
                .build();

        SleepWorker worker =
                (SleepWorker) TestWorkerBuilder.from(context,
                        SleepWorker.class, executor)
                        .setInputData(inputData)
                        .build();

        Result result = worker.doWork();
        assertThat(result, is(Result.success()));
    }
}

لمزيد من التفاصيل حول TestWorkerBuilder API، يُرجى الاطّلاع على الصفحة المرجعية الخاصة TestListenableWorkerBuilder, الفئة الفائقة TestWorkerBuilder.

اختبار ListenableWorker وأشكاله المختلفة

لاختبار ListenableWorker أو خيارات المنتج (CoroutineWorker وRxWorker)، استخدم TestListenableWorkerBuilder. يتمثل الاختلاف الرئيسي بين TestWorkerBuilder TestListenableWorkerBuilder هو أنّ TestWorkerBuilder يتيح لك تحديد الخلفية التي اعتاد Executor عليها تشغيل Worker، بينما يعتمد TestListenableWorkerBuilder على منطق تسلسُل تنفيذ ListenableWorker.

على سبيل المثال، لنفترض أنّنا بحاجة إلى اختبار CoroutineWorker الذي يبدو على النحو التالي:

class SleepWorker(context: Context, parameters: WorkerParameters) :
    CoroutineWorker(context, parameters) {
    override suspend fun doWork(): Result {
        delay(1000L) // milliseconds
        return Result.success()
    }
}

لاختبار SleepWorker، ننشئ أولاً مثيلاً للعامل باستخدام TestListenableWorkerBuilder ثم استدعِ الدالة doWork داخل الكوروتين.

@RunWith(AndroidJUnit4::class)
class SleepWorkerTest {
    private lateinit var context: Context

    @Before
    fun setUp() {
        context = ApplicationProvider.getApplicationContext()
    }

    @Test
    fun testSleepWorker() {
        val worker = TestListenableWorkerBuilder<SleepWorker>(context).build()
        runBlocking {
            val result = worker.doWork()
            assertThat(result, `is`(Result.success()))
        }
    }
}

من المنطقي استخدام "runBlocking" كأداة لإنشاء الكوروتين في اختباراتك، وذلك لكي لا يتم تطبيق أي رمز التي سيتم تنفيذها بشكل غير متزامن بدلاً من ذلك يتم تشغيلها بالتوازي.

إنّ اختبار عملية تنفيذ RxWorker يشبه اختبار CoroutineWorker، حيث يمكن لـ TestListenableWorkerBuilder التعامل مع أي فئة فرعية من ListenableWorker. يمكنك تجربة نسخة من SleepWorker تستخدم خوارزمية RxJava بدلاً من الكوروتينات.

Kotlin

class SleepWorker(
    context: Context,
    parameters: WorkerParameters
) : RxWorker(context, parameters) {
    override fun createWork(): SingleR<esult >{
        return Single.just(Result.success())
            .delay(1000L, TimeUnit.MILLISECONDS)
    }
}

Java

public class SleepWorker extends RxWorker {
    public SleepWorker(@NonNull Context appContext, 
@NonNull WorkerParameters workerParams) {
        super(appContext, workerParams);
    }

    @NonNull
    @Override
    public SingleR<esult >createWork() {
        return Single.just(Result.success())
                .delay(1000L, TimeUnit.MILLISECONDS);
    }
}

قد يبدو إصدار SleepWorkerTest الذي يختبر RxWorker مشابهًا للإصدار الإصدار الذي اختبر CoroutineWorker. تستخدم نفس الاتصال الآن بـ "createWork" الخاص بـ "RxWorker" من قِبل "TestListenableWorkerBuilder" الأخرى. تُرجع createWork Single يمكنك استخدامه للتحقق من سلوك العامل لديك. تعالج الإضافة "TestListenableWorkerBuilder" أي سلاسل محادثات. التعقيدات وينفذ التعليمات البرمجية العامل بالتوازي.

Kotlin

@RunWith(AndroidJUnit4::class)
class SleepWorkerTest {
    private lateinit var context: Context

    @Before
    fun setUp() {
        context = ApplicationProvider.getApplicationContext()
    }

    @Test
    fun testSleepWorker() {
        val worker = TestListenableWorkerBuilderS<leepWorker(>context).build()
        worker.createWork().subscribe { result -
>            assertThat(result, `is`(Result.success()))
        }
    }
}

Java

@RunWith(AndroidJUnit4.class)
public class SleepWorkerTest {
    private Context context;

    @Before
    public void setUp() {
        context = ApplicationProvider.getApplicationContext();
    }

    @Test
    public void testSleepWorker() {
        SleepWorker worker = TestListenableWorkerBuilder.from(context, SleepWorker.class)
                .build();
        worker.createWork().subscribe(result -
>                assertThat(result, is(Result.success())));
        }
}