Google은 흑인 공동체를 위한 인종 간 평등을 진전시키기 위해 노력하고 있습니다. Google에서 어떤 노력을 하고 있는지 확인하세요.

작업자 구현 테스트

WorkManager는 Worker, ListenableWorker, ListenableWorker 변형(CoroutineWorkerRxWorker) 테스트를 위한 API를 제공합니다.

작업자 테스트

다음과 같은 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()
    }
}

자바


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 = TestWorkerBuilder<SleepWorker>(
            context = context,
            executor = executor
        ).build()

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

자바


@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가 Worker에 정의된 상수가 아닌 절전 모드 지속 시간을 입력 데이터로 취하는 경우를 예로 들어 보겠습니다.

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"
    }
}

자바


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 = TestWorkerBuilder<SleepWorker>(
            context = context,
            executor = executor,
            inputData = workDataOf("SLEEP_DURATION" to 1000L)
        ).build()

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

자바


@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에 관한 자세한 내용은 TestWorkerBuilder의 슈퍼클래스인 TestListenableWorkerBuilder의 참조 페이지를 확인하세요.

ListenableWorker 및 변형 테스트

ListenableWorker 또는 변형(CoroutineWorkerRxWorker)을 테스트하려면 TestListenableWorkerBuilder를 사용합니다. TestWorkerBuilderTestListenableWorkerBuilder의 주요 차이점은 TestWorkerBuilderWorker를 실행하는 데 사용되는 백그라운드 Executor를 지정할 수 있는 반면 TestListenableWorkerBuilderListenableWorker 구현의 스레딩 로직을 사용한다는 점입니다.

예를 들어 다음과 같이 CoroutineWorker를 테스트해야 한다고 가정해 보겠습니다.

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

SleepWorker를 테스트하기 위해 먼저 TestListenableWorkerBuilder를 사용하는 Worker 인스턴스를 만든 다음 코루틴 내에서 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이 테스트용 코루틴 빌더로 타당합니다.

TestListenableWorkerBuilderListenableWorker의 서브클래스를 처리할 수 있으므로 RxWorker 구현을 테스트하는 것은 CoroutineWorker 테스트와 유사합니다. 코루틴 대신 RxJava를 사용하는 SleepWorker 버전을 생각해 보세요.

Kotlin


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

자바


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

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

RxWorker를 테스트하는 SleepWorkerTest 버전은 CoroutineWorker를 테스트한 버전과 유사할 수 있습니다. 동일한 TestListenableWorkerBuilder를 사용하지만 이제는 RxWorkercreateWork 함수를 호출합니다. 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 = TestListenableWorkerBuilder<SleepWorker>(context).build()
        worker.createWork().subscribe { result ->
            assertThat(result, `is`(Result.success()))
        }
    }
}

자바


@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())));
        }
}