У меня есть приложение, которое использует UseCases для доступа к репозиторию. UseCases подписываются на пул потоков, хранилище делает сетевые запросы, используя пул потоков OkHttp, а хранилище также выполняет запись в базу данных, которая использует пул потоков Schedulers.io ().
В некоторых версиях Android у меня возникают проблемы с запуском тестов пользовательского интерфейса с помощью Espresso, потому что мои ресурсы бездействия, кажется, бездействуют до того, как все сетевые запросы / записи в базу данных завершены.
AFAIK, моя установка использует три разных пула потоков. Я думал, что если в моем тесте пользовательского интерфейса я создаю ресурс ожидания, который наблюдает за каждым пулом потоков, то при вызове моего репозитория через UseCase Espresso будет ждать до тех пор, пока все пулы потоков будут бездействовать, прежде чем он переместит мой тестовый код.
Вот пример моего тестового кода:
val wrapped: IdlingResourceScheduler = Rx2Idler.wrap(application.component.providesIoScheduler(), "IO Scheduler")
val otherWrapped: IdlingResourceScheduler = Rx2Idler.wrap(application.component.providesJobScheduler(), "J O B")
val resource = arrayOf<IdlingResource>(okHttpIdlingResource, wrapped, otherWrapped)
idlingRegistry.goIdle(*resource) {
onView(withId(R.id.toolbar_main))
.check(matches(isDisplayed()))
}
То, что я делаю в приведенном выше коде, - это регистрация ресурса холостого хода для моего пула потоков базы данных, моего пула потоков OkHttp и моего пула потоков UseCase. Поэтому я подумал, что по крайней мере один из этих пулов потоков будет всегда «активным», когда будет сделан вызов в мой репозиторий, и как только репозиторий вернет свое значение, все пулы потоков будут простаивать, и Espresso будет знать, что это хорошо, чтобы продвинуть тест. Как я уже говорил выше, это похоже на устройства под управлением Marshmallow (и, возможно, даже более высоких версий), но не работает на устройствах на Pie.
Вот упрощенный пример моего UseCase:
repository
.authenticate(params.username, params.password)
.subscribeOn(My Use Case Thread Pool)
.observeOn(Main Thread)
Вот упрощенный пример метода auth в моем классе репозитория:
Single.zip(networkLayer.authenticate(username, password),
userDao.getUserInfo(),
BiFunction { t1, t2 -> Result(t1,t2) }
.flatMap {
Single.just(deleteAllDataFromDatabase())
.flatMap {
networkLayer.getRestOfData()
}
}
Что я действительно не могу понять, так это то, почему тест выполняется на некоторых версиях, но не на других. Я также не могу понять, почему, если я смотрю все пулы потоков на бездействие, как Espresso может продвинуть тест? Не будет ли хотя бы один из моих пулов потоков что-то делать (либо извлекать данные из сети, записывать в базу данных, либо делать что-то в сценарии использования? Чего мне не хватает?