Issue#67 Extract MainThread synchronization into a separate module
This commit is contained in:
parent
1c0153db75
commit
bbe077dde8
8 changed files with 36 additions and 42 deletions
|
|
@ -16,7 +16,7 @@ import org.fnives.test.showcase.testutils.idling.CompositeDisposable
|
||||||
import org.fnives.test.showcase.testutils.idling.Disposable
|
import org.fnives.test.showcase.testutils.idling.Disposable
|
||||||
import org.fnives.test.showcase.testutils.idling.IdlingResourceDisposable
|
import org.fnives.test.showcase.testutils.idling.IdlingResourceDisposable
|
||||||
import org.fnives.test.showcase.testutils.idling.OkHttp3IdlingResource
|
import org.fnives.test.showcase.testutils.idling.OkHttp3IdlingResource
|
||||||
import org.fnives.test.showcase.testutils.idling.loopMainThreadFor
|
import org.fnives.test.showcase.android.testutil.synchronization.loopMainThreadFor
|
||||||
import org.fnives.test.showcase.testutils.storage.TestDatabaseInitialization
|
import org.fnives.test.showcase.testutils.storage.TestDatabaseInitialization
|
||||||
import org.fnives.test.showcase.ui.splash.SplashActivity
|
import org.fnives.test.showcase.ui.splash.SplashActivity
|
||||||
import org.hamcrest.Description
|
import org.hamcrest.Description
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,8 @@
|
||||||
package org.fnives.test.showcase.testutils.idling
|
package org.fnives.test.showcase.testutils.idling
|
||||||
|
|
||||||
import android.os.Looper
|
|
||||||
import androidx.test.espresso.Espresso
|
|
||||||
import androidx.test.espresso.IdlingRegistry
|
import androidx.test.espresso.IdlingRegistry
|
||||||
import androidx.test.espresso.IdlingResource
|
import androidx.test.espresso.IdlingResource
|
||||||
import androidx.test.espresso.matcher.ViewMatchers
|
import org.fnives.test.showcase.android.testutil.synchronization.loopMainThreadFor
|
||||||
import org.fnives.test.showcase.testutils.viewactions.LoopMainThreadFor
|
|
||||||
import org.fnives.test.showcase.testutils.viewactions.LoopMainThreadUntilIdle
|
|
||||||
import java.util.concurrent.Executors
|
import java.util.concurrent.Executors
|
||||||
|
|
||||||
// workaround, issue with idlingResources is tracked here https://github.com/robolectric/robolectric/issues/4807
|
// workaround, issue with idlingResources is tracked here https://github.com/robolectric/robolectric/issues/4807
|
||||||
|
|
@ -41,20 +37,3 @@ private fun IdlingResource.awaitUntilIdle() {
|
||||||
Thread.sleep(100L)
|
Thread.sleep(100L)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun loopMainThreadUntilIdleWithIdlingResources() {
|
|
||||||
Espresso.onView(ViewMatchers.isRoot()).perform(LoopMainThreadUntilIdle()) // advance until a request is sent
|
|
||||||
while (anyResourceIdling()) { // check if any request is in progress
|
|
||||||
awaitIdlingResources() // complete all requests and other idling resources
|
|
||||||
Espresso.onView(ViewMatchers.isRoot()).perform(LoopMainThreadUntilIdle()) // run coroutines after request is finished
|
|
||||||
}
|
|
||||||
Espresso.onView(ViewMatchers.isRoot()).perform(LoopMainThreadUntilIdle())
|
|
||||||
}
|
|
||||||
|
|
||||||
fun loopMainThreadFor(delay: Long) {
|
|
||||||
if (Looper.getMainLooper().isCurrentThread) {
|
|
||||||
Thread.sleep(200L)
|
|
||||||
} else {
|
|
||||||
Espresso.onView(ViewMatchers.isRoot()).perform(LoopMainThreadFor(delay))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ package org.fnives.test.showcase.ui.home
|
||||||
import androidx.test.core.app.ActivityScenario
|
import androidx.test.core.app.ActivityScenario
|
||||||
import androidx.test.espresso.intent.Intents
|
import androidx.test.espresso.intent.Intents
|
||||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
|
import org.fnives.test.showcase.android.testutil.activity.safeClose
|
||||||
import org.fnives.test.showcase.model.content.FavouriteContent
|
import org.fnives.test.showcase.model.content.FavouriteContent
|
||||||
import org.fnives.test.showcase.network.mockserver.ContentData
|
import org.fnives.test.showcase.network.mockserver.ContentData
|
||||||
import org.fnives.test.showcase.network.mockserver.scenario.content.ContentScenario
|
import org.fnives.test.showcase.network.mockserver.scenario.content.ContentScenario
|
||||||
|
|
@ -10,9 +11,7 @@ import org.fnives.test.showcase.network.mockserver.scenario.refresh.RefreshToken
|
||||||
import org.fnives.test.showcase.testutils.MockServerScenarioSetupResetingTestRule
|
import org.fnives.test.showcase.testutils.MockServerScenarioSetupResetingTestRule
|
||||||
import org.fnives.test.showcase.testutils.idling.AsyncDiffUtilInstantTestRule
|
import org.fnives.test.showcase.testutils.idling.AsyncDiffUtilInstantTestRule
|
||||||
import org.fnives.test.showcase.testutils.idling.MainDispatcherTestRule
|
import org.fnives.test.showcase.testutils.idling.MainDispatcherTestRule
|
||||||
import org.fnives.test.showcase.testutils.idling.loopMainThreadFor
|
import org.fnives.test.showcase.android.testutil.synchronization.loopMainThreadFor
|
||||||
import org.fnives.test.showcase.testutils.idling.loopMainThreadUntilIdleWithIdlingResources
|
|
||||||
import org.fnives.test.showcase.android.testutil.activity.safeClose
|
|
||||||
import org.fnives.test.showcase.testutils.statesetup.SetupAuthenticationState.setupLogin
|
import org.fnives.test.showcase.testutils.statesetup.SetupAuthenticationState.setupLogin
|
||||||
import org.junit.After
|
import org.junit.After
|
||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
|
|
@ -175,9 +174,6 @@ class MainActivityInstrumentedTest : KoinTest {
|
||||||
|
|
||||||
robot.swipeRefresh()
|
robot.swipeRefresh()
|
||||||
mainDispatcherTestRule.advanceUntilIdleWithIdlingResources()
|
mainDispatcherTestRule.advanceUntilIdleWithIdlingResources()
|
||||||
loopMainThreadUntilIdleWithIdlingResources()
|
|
||||||
mainDispatcherTestRule.advanceTimeBy(1000L)
|
|
||||||
loopMainThreadFor(1000)
|
|
||||||
|
|
||||||
robot
|
robot
|
||||||
.assertContainsError()
|
.assertContainsError()
|
||||||
|
|
|
||||||
|
|
@ -30,5 +30,5 @@ project.ext {
|
||||||
testing_json_assert_version = "1.5.0"
|
testing_json_assert_version = "1.5.0"
|
||||||
testing_junit4_version = "4.12"
|
testing_junit4_version = "4.12"
|
||||||
testing_robolectric_version = "4.7"
|
testing_robolectric_version = "4.7"
|
||||||
testing_espresso_version = "3.4.0"
|
espresso_version = "3.4.0"
|
||||||
}
|
}
|
||||||
|
|
@ -32,4 +32,5 @@ android {
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:$coroutines_version"
|
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:$coroutines_version"
|
||||||
implementation "androidx.test:core:$androidx_test_version"
|
implementation "androidx.test:core:$androidx_test_version"
|
||||||
|
implementation"androidx.test.espresso:espresso-core:$espresso_version"
|
||||||
}
|
}
|
||||||
|
|
@ -2,8 +2,11 @@ package org.fnives.test.showcase.android.testutil.synchronization
|
||||||
|
|
||||||
import android.os.Handler
|
import android.os.Handler
|
||||||
import android.os.Looper
|
import android.os.Looper
|
||||||
|
import androidx.test.espresso.Espresso
|
||||||
|
import androidx.test.espresso.matcher.ViewMatchers
|
||||||
import kotlinx.coroutines.CompletableDeferred
|
import kotlinx.coroutines.CompletableDeferred
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
|
import org.fnives.test.showcase.android.testutil.viewaction.LoopMainThreadFor
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Runs the given action on the MainThread and blocks currentThread, until it is completed.
|
* Runs the given action on the MainThread and blocks currentThread, until it is completed.
|
||||||
|
|
@ -22,3 +25,11 @@ fun runOnUIAwaitOnCurrent(action: () -> Unit) {
|
||||||
runBlocking { deferred.await() }
|
runBlocking { deferred.await() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun loopMainThreadFor(delay: Long) {
|
||||||
|
if (Looper.getMainLooper().thread == Thread.currentThread()) {
|
||||||
|
Thread.sleep(200L)
|
||||||
|
} else {
|
||||||
|
Espresso.onView(ViewMatchers.isRoot()).perform(LoopMainThreadFor(delay))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package org.fnives.test.showcase.testutils.viewactions
|
package org.fnives.test.showcase.android.testutil.viewaction
|
||||||
|
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import androidx.test.espresso.UiController
|
import androidx.test.espresso.UiController
|
||||||
|
|
@ -14,14 +14,4 @@ class LoopMainThreadFor(private val delayInMillis: Long) : ViewAction {
|
||||||
override fun perform(uiController: UiController, view: View?) {
|
override fun perform(uiController: UiController, view: View?) {
|
||||||
uiController.loopMainThreadForAtLeast(delayInMillis)
|
uiController.loopMainThreadForAtLeast(delayInMillis)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class LoopMainThreadUntilIdle : ViewAction {
|
|
||||||
override fun getConstraints(): Matcher<View> = Matchers.isA(View::class.java)
|
|
||||||
|
|
||||||
override fun getDescription(): String = "loop MainThread for until Idle"
|
|
||||||
|
|
||||||
override fun perform(uiController: UiController, view: View?) {
|
|
||||||
uiController.loopMainThreadUntilIdle()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
package org.fnives.test.showcase.android.testutil.viewaction
|
||||||
|
|
||||||
|
import android.view.View
|
||||||
|
import androidx.test.espresso.UiController
|
||||||
|
import androidx.test.espresso.ViewAction
|
||||||
|
import org.hamcrest.Matcher
|
||||||
|
import org.hamcrest.Matchers
|
||||||
|
|
||||||
|
class LoopMainThreadUntilIdle : ViewAction {
|
||||||
|
override fun getConstraints(): Matcher<View> = Matchers.isA(View::class.java)
|
||||||
|
|
||||||
|
override fun getDescription(): String = "loop MainThread for until Idle"
|
||||||
|
|
||||||
|
override fun perform(uiController: UiController, view: View?) {
|
||||||
|
uiController.loopMainThreadUntilIdle()
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue