Merge "Use TestLifecycleOwner in all tests" into androidx-master-dev
diff --git a/activity/activity-ktx/build.gradle b/activity/activity-ktx/build.gradle
index 876ae95..c728b82 100644
--- a/activity/activity-ktx/build.gradle
+++ b/activity/activity-ktx/build.gradle
@@ -43,6 +43,8 @@
     }
     api(project(":lifecycle:lifecycle-viewmodel-ktx"))
     api(KOTLIN_STDLIB)
+
+    androidTestImplementation(project(":lifecycle:lifecycle-runtime-testing"))
     androidTestImplementation(JUNIT)
     androidTestImplementation(TRUTH)
     androidTestImplementation(ANDROIDX_TEST_EXT_JUNIT)
diff --git a/activity/activity-ktx/src/androidTest/java/androidx/activity/OnBackPressedDispatcherTest.kt b/activity/activity-ktx/src/androidTest/java/androidx/activity/OnBackPressedDispatcherTest.kt
index 98090b0..0a08e5f 100644
--- a/activity/activity-ktx/src/androidTest/java/androidx/activity/OnBackPressedDispatcherTest.kt
+++ b/activity/activity-ktx/src/androidTest/java/androidx/activity/OnBackPressedDispatcherTest.kt
@@ -17,8 +17,7 @@
 package androidx.activity
 
 import androidx.lifecycle.Lifecycle
-import androidx.lifecycle.LifecycleOwner
-import androidx.lifecycle.LifecycleRegistry
+import androidx.lifecycle.testing.TestLifecycleOwner
 import androidx.test.annotation.UiThreadTest
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
@@ -83,11 +82,7 @@
     @UiThreadTest
     @Test
     fun testLifecycleCallback() {
-        val lifecycleOwner = object : LifecycleOwner {
-            val lifecycleRegistry = LifecycleRegistry(this)
-
-            override fun getLifecycle() = lifecycleRegistry
-        }
+        val lifecycleOwner = TestLifecycleOwner(Lifecycle.State.INITIALIZED)
         var count = 0
         dispatcher.addCallback(lifecycleOwner) {
             count++
@@ -101,14 +96,14 @@
             .isEqualTo(0)
 
         // Now start the Lifecycle
-        lifecycleOwner.lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START)
+        lifecycleOwner.handleLifecycleEvent(Lifecycle.Event.ON_START)
         dispatcher.onBackPressed()
         assertWithMessage("Once the callbacks is started, the count should increment")
             .that(count)
             .isEqualTo(1)
 
         // Now stop the Lifecycle
-        lifecycleOwner.lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_STOP)
+        lifecycleOwner.handleLifecycleEvent(Lifecycle.Event.ON_STOP)
         assertWithMessage("Handler should return false if the Lifecycle isn't started")
             .that(dispatcher.hasEnabledCallbacks())
             .isFalse()
diff --git a/activity/activity/build.gradle b/activity/activity/build.gradle
index ed3d81d..b4d1104 100644
--- a/activity/activity/build.gradle
+++ b/activity/activity/build.gradle
@@ -24,6 +24,7 @@
     api("androidx.savedstate:savedstate:1.0.0")
     api(project(":lifecycle:lifecycle-viewmodel-savedstate"))
 
+    androidTestImplementation(project(":lifecycle:lifecycle-runtime-testing"))
     androidTestImplementation(KOTLIN_STDLIB)
     androidTestImplementation(ANDROIDX_TEST_EXT_JUNIT)
     androidTestImplementation(ANDROIDX_TEST_CORE)
diff --git a/activity/activity/src/androidTest/java/androidx/activity/OnBackPressedDispatcherTest.kt b/activity/activity/src/androidTest/java/androidx/activity/OnBackPressedDispatcherTest.kt
index ec04cec..d59289b 100644
--- a/activity/activity/src/androidTest/java/androidx/activity/OnBackPressedDispatcherTest.kt
+++ b/activity/activity/src/androidTest/java/androidx/activity/OnBackPressedDispatcherTest.kt
@@ -17,8 +17,7 @@
 package androidx.activity
 
 import androidx.lifecycle.Lifecycle
-import androidx.lifecycle.LifecycleOwner
-import androidx.lifecycle.LifecycleRegistry
+import androidx.lifecycle.testing.TestLifecycleOwner
 import androidx.test.annotation.UiThreadTest
 import androidx.test.core.app.ActivityScenario
 import androidx.test.ext.junit.runners.AndroidJUnit4
@@ -227,11 +226,7 @@
     fun testLifecycleCallback() {
         val onBackPressedCallback = CountingOnBackPressedCallback()
         val lifecycleOnBackPressedCallback = CountingOnBackPressedCallback()
-        val lifecycleOwner = object : LifecycleOwner {
-            val lifecycleRegistry = LifecycleRegistry(this)
-
-            override fun getLifecycle() = lifecycleRegistry
-        }
+        val lifecycleOwner = TestLifecycleOwner(Lifecycle.State.INITIALIZED)
 
         dispatcher.addCallback(onBackPressedCallback)
         dispatcher.addCallback(lifecycleOwner, lifecycleOnBackPressedCallback)
@@ -245,7 +240,7 @@
             .isEqualTo(1)
 
         // Now start the Lifecycle
-        lifecycleOwner.lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START)
+        lifecycleOwner.handleLifecycleEvent(Lifecycle.Event.ON_START)
         dispatcher.onBackPressed()
         assertWithMessage("Once the callbacks is started, the count should increment")
             .that(lifecycleOnBackPressedCallback.count)
@@ -255,7 +250,7 @@
             .isEqualTo(1)
 
         // Now stop the Lifecycle
-        lifecycleOwner.lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_STOP)
+        lifecycleOwner.handleLifecycleEvent(Lifecycle.Event.ON_STOP)
         dispatcher.onBackPressed()
         assertWithMessage("Non-started callbacks shouldn't have their count incremented")
             .that(lifecycleOnBackPressedCallback.count)
@@ -266,7 +261,7 @@
             .isEqualTo(2)
 
         // Now destroy the Lifecycle
-        lifecycleOwner.lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY)
+        lifecycleOwner.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY)
         dispatcher.onBackPressed()
         assertWithMessage("Non-started callbacks shouldn't have their count incremented")
             .that(lifecycleOnBackPressedCallback.count)
@@ -286,12 +281,7 @@
                 remove()
             }
         }
-        val lifecycleOwner = object : LifecycleOwner {
-            val lifecycleRegistry = LifecycleRegistry(this)
-
-            override fun getLifecycle() = lifecycleRegistry
-        }
-        lifecycleOwner.lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START)
+        val lifecycleOwner = TestLifecycleOwner()
 
         dispatcher.addCallback(lifecycleOwner, onBackPressedCallback)
         assertWithMessage("Handler should return true once a callback is added")
@@ -317,13 +307,7 @@
     @Test
     fun testLifecycleCallbackDestroyed() {
         val onBackPressedCallback = CountingOnBackPressedCallback()
-        val lifecycleOwner = object : LifecycleOwner {
-            val lifecycleRegistry = LifecycleRegistry(this)
-
-            override fun getLifecycle() = lifecycleRegistry
-        }
-        // Start the Lifecycle at CREATED
-        lifecycleOwner.lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE)
+        val lifecycleOwner = TestLifecycleOwner(Lifecycle.State.CREATED)
 
         dispatcher.addCallback(lifecycleOwner, onBackPressedCallback)
         assertWithMessage("Non-started callbacks shouldn't appear as an enabled dispatcher")
@@ -331,14 +315,14 @@
             .isFalse()
 
         // Now destroy the Lifecycle
-        lifecycleOwner.lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY)
+        lifecycleOwner.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY)
         assertWithMessage("Destroyed callbacks shouldn't appear as an enabled dispatcher")
             .that(dispatcher.hasEnabledCallbacks())
             .isFalse()
 
         // Now start the Lifecycle - this wouldn't happen in a real Lifecycle since DESTROYED
         // is terminal but serves as a good test to make sure the Observer is cleaned up
-        lifecycleOwner.lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START)
+        lifecycleOwner.handleLifecycleEvent(Lifecycle.Event.ON_START)
         assertWithMessage("Previously destroyed callbacks shouldn't appear as an enabled " +
                 "dispatcher")
             .that(dispatcher.hasEnabledCallbacks())
@@ -349,13 +333,8 @@
     @Test
     fun testLifecycleCallback_whenDestroyed() {
         val lifecycleOnBackPressedCallback = CountingOnBackPressedCallback()
-        val lifecycleOwner = object : LifecycleOwner {
-            val lifecycleRegistry = LifecycleRegistry(this)
 
-            override fun getLifecycle() = lifecycleRegistry
-        }
-        // Start the Lifecycle as DESTROYED
-        lifecycleOwner.lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY)
+        val lifecycleOwner = TestLifecycleOwner(Lifecycle.State.DESTROYED)
 
         dispatcher.addCallback(lifecycleOwner, lifecycleOnBackPressedCallback)
 
@@ -366,7 +345,7 @@
 
         // Now start the Lifecycle - this wouldn't happen in a real Lifecycle since DESTROYED
         // is terminal but serves as a good test to make sure no lingering Observer exists
-        lifecycleOwner.lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START)
+        lifecycleOwner.handleLifecycleEvent(Lifecycle.Event.ON_START)
         assertWithMessage("Previously destroyed callbacks shouldn't appear as an enabled " +
                 "dispatcher")
             .that(dispatcher.hasEnabledCallbacks())
diff --git a/camera/camera-camera2/build.gradle b/camera/camera-camera2/build.gradle
index 51aaff2..161598a 100644
--- a/camera/camera-camera2/build.gradle
+++ b/camera/camera-camera2/build.gradle
@@ -41,6 +41,8 @@
     testImplementation(TRUTH)
     testImplementation(ROBOLECTRIC)
     testImplementation(MOCKITO_CORE)
+    testImplementation(KOTLIN_COROUTINES_TEST)
+    testImplementation(project(":lifecycle:lifecycle-runtime-testing"))
     testImplementation(project(":camera:camera-testing"))
 
     androidTestImplementation(ANDROIDX_TEST_EXT_JUNIT)
diff --git a/camera/camera-camera2/src/test/java/androidx/camera/camera2/internal/TorchControlTest.java b/camera/camera-camera2/src/test/java/androidx/camera/camera2/internal/TorchControlTest.java
index 757f13e..60de6eb 100644
--- a/camera/camera-camera2/src/test/java/androidx/camera/camera2/internal/TorchControlTest.java
+++ b/camera/camera-camera2/src/test/java/androidx/camera/camera2/internal/TorchControlTest.java
@@ -37,10 +37,9 @@
 import androidx.camera.core.TorchState;
 import androidx.camera.core.impl.CameraControlInternal;
 import androidx.lifecycle.Lifecycle;
-import androidx.lifecycle.LifecycleOwner;
-import androidx.lifecycle.LifecycleRegistry;
 import androidx.lifecycle.LiveData;
 import androidx.lifecycle.Observer;
+import androidx.lifecycle.testing.TestLifecycleOwner;
 import androidx.test.core.app.ApplicationProvider;
 import androidx.test.filters.SmallTest;
 
@@ -63,6 +62,8 @@
 import java.util.concurrent.Executors;
 import java.util.concurrent.ScheduledExecutorService;
 
+import kotlinx.coroutines.test.TestCoroutineDispatcher;
+
 @SmallTest
 @RunWith(RobolectricTestRunner.class)
 @DoNotInstrument
@@ -75,8 +76,7 @@
     private TorchControl mNoFlashUnitTorchControl;
     private TorchControl mTorchControl;
     private Camera2CameraControl.CaptureResultListener mCaptureResultListener;
-    private LifecycleOwner mLifecycleOwner;
-    private LifecycleRegistry mLifecycleRegistry;
+    private TestLifecycleOwner mLifecycleOwner;
 
     @Before
     public void setUp() throws CameraAccessException {
@@ -112,10 +112,8 @@
         mCaptureResultListener = argumentCaptor.getValue();
 
         /* Prepare Lifecycle for test LiveData */
-        mLifecycleOwner = mock(LifecycleOwner.class);
-        mLifecycleRegistry = new LifecycleRegistry(mLifecycleOwner);
-        when(mLifecycleOwner.getLifecycle()).thenReturn(mLifecycleRegistry);
-        mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START);
+        mLifecycleOwner = new TestLifecycleOwner(Lifecycle.State.STARTED,
+                new TestCoroutineDispatcher());
     }
 
     @After
diff --git a/lifecycle/integration-tests/kotlintestapp/build.gradle b/lifecycle/integration-tests/kotlintestapp/build.gradle
index 0eb64c2..48d5266 100644
--- a/lifecycle/integration-tests/kotlintestapp/build.gradle
+++ b/lifecycle/integration-tests/kotlintestapp/build.gradle
@@ -33,7 +33,10 @@
     testImplementation(TRUTH)
     testImplementation(KOTLIN_COROUTINES_ANDROID)
     testImplementation(KOTLIN_COROUTINES_TEST)
+    testImplementation(project(":lifecycle:lifecycle-runtime-testing"))
 
+    androidTestImplementation(project(":lifecycle:lifecycle-runtime-testing"))
+    androidTestImplementation(KOTLIN_COROUTINES_TEST)
     androidTestImplementation(KOTLIN_COROUTINES_ANDROID)
     androidTestImplementation(ANDROIDX_TEST_EXT_KTX)
     androidTestImplementation(TRUTH)
diff --git a/lifecycle/integration-tests/kotlintestapp/src/test-common/java/androidx.lifecycle/FakeLifecycleOwner.kt b/lifecycle/integration-tests/kotlintestapp/src/test-common/java/androidx.lifecycle/FakeLifecycleOwner.kt
deleted file mode 100644
index 9bb260b..0000000
--- a/lifecycle/integration-tests/kotlintestapp/src/test-common/java/androidx.lifecycle/FakeLifecycleOwner.kt
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.lifecycle
-
-class FakeLifecycleOwner(initialState: Lifecycle.State? = null) : LifecycleOwner {
-    private val registry: LifecycleRegistry = LifecycleRegistry(this)
-
-    init {
-        initialState?.let {
-            setState(it)
-        }
-    }
-
-    override fun getLifecycle(): Lifecycle = registry
-
-    fun setState(state: Lifecycle.State) {
-        registry.currentState = state
-    }
-}
\ No newline at end of file
diff --git a/lifecycle/integration-tests/kotlintestapp/src/test-common/java/androidx.lifecycle/LifecycleCoroutineScopeTestBase.kt b/lifecycle/integration-tests/kotlintestapp/src/test-common/java/androidx.lifecycle/LifecycleCoroutineScopeTestBase.kt
index 4c4d7e0..f582ae0 100644
--- a/lifecycle/integration-tests/kotlintestapp/src/test-common/java/androidx.lifecycle/LifecycleCoroutineScopeTestBase.kt
+++ b/lifecycle/integration-tests/kotlintestapp/src/test-common/java/androidx.lifecycle/LifecycleCoroutineScopeTestBase.kt
@@ -16,6 +16,7 @@
 
 package androidx.lifecycle
 
+import androidx.lifecycle.testing.TestLifecycleOwner
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -24,6 +25,7 @@
 import kotlinx.coroutines.launch
 import kotlinx.coroutines.runBlocking
 import kotlinx.coroutines.sync.Mutex
+import kotlinx.coroutines.test.TestCoroutineDispatcher
 import kotlinx.coroutines.withContext
 import org.junit.Test
 import java.util.concurrent.CancellationException
@@ -32,19 +34,19 @@
 abstract class LifecycleCoroutineScopeTestBase {
     @Test
     fun initialization() {
-        val owner = FakeLifecycleOwner(Lifecycle.State.INITIALIZED)
+        val owner = TestLifecycleOwner(Lifecycle.State.INITIALIZED, TestCoroutineDispatcher())
         val scope = owner.lifecycleScope
         assertThat(owner.lifecycle.mInternalScopeRef.get()).isSameInstanceAs(scope)
         val scope2 = owner.lifecycleScope
         assertThat(scope).isSameInstanceAs(scope2)
         runBlocking(Dispatchers.Main) {
-            assertThat((owner.lifecycle as LifecycleRegistry).observerCount).isEqualTo(1)
+            assertThat(owner.observerCount).isEqualTo(1)
         }
     }
 
     @Test
     fun simpleLaunch() {
-        val owner = FakeLifecycleOwner(Lifecycle.State.INITIALIZED)
+        val owner = TestLifecycleOwner(Lifecycle.State.INITIALIZED, TestCoroutineDispatcher())
         assertThat(
             runBlocking {
                 owner.lifecycleScope.async {
@@ -57,7 +59,7 @@
 
     @Test
     fun launchAfterDestroy() {
-        val owner = FakeLifecycleOwner(Lifecycle.State.DESTROYED)
+        val owner = TestLifecycleOwner(Lifecycle.State.DESTROYED, TestCoroutineDispatcher())
         runBlocking {
             owner.lifecycleScope.launch {
                 // do nothing
@@ -68,7 +70,7 @@
 
     @Test
     fun launchOnMain() {
-        val owner = FakeLifecycleOwner(Lifecycle.State.STARTED)
+        val owner = TestLifecycleOwner(Lifecycle.State.STARTED, TestCoroutineDispatcher())
         assertThat(
             runBlocking(Dispatchers.Main) {
                 owner.lifecycleScope.async {
@@ -80,7 +82,7 @@
 
     @Test
     fun launchOnIO() {
-        val owner = FakeLifecycleOwner(Lifecycle.State.STARTED)
+        val owner = TestLifecycleOwner(Lifecycle.State.STARTED, TestCoroutineDispatcher())
         assertThat(
             runBlocking(Dispatchers.IO) {
                 owner.lifecycleScope.async {
@@ -94,14 +96,14 @@
     fun destroyWhileRunning() {
         val startMutex = Mutex(locked = true)
         val alwaysLocked = Mutex(locked = true)
-        val owner = FakeLifecycleOwner(Lifecycle.State.STARTED)
+        val owner = TestLifecycleOwner(Lifecycle.State.STARTED, TestCoroutineDispatcher())
         val actionWasActive = owner.lifecycleScope.async(Dispatchers.IO) {
             startMutex.unlock()
             alwaysLocked.lock() // wait 4ever
         }
         runBlocking(Dispatchers.Main) {
             startMutex.lock() // wait until it starts
-            owner.setState(Lifecycle.State.DESTROYED)
+            owner.currentState = Lifecycle.State.DESTROYED
             actionWasActive.join()
             assertThat(actionWasActive.isCancelled).isTrue()
         }
@@ -109,7 +111,7 @@
 
     @Test
     fun throwException() {
-        val owner = FakeLifecycleOwner(Lifecycle.State.STARTED)
+        val owner = TestLifecycleOwner(Lifecycle.State.STARTED, TestCoroutineDispatcher())
         runBlocking {
             val action = owner.lifecycleScope.async {
                 throw RuntimeException("foo")
@@ -122,14 +124,14 @@
 
     @Test
     fun throwException_onStart() {
-        val owner = FakeLifecycleOwner(Lifecycle.State.CREATED)
+        val owner = TestLifecycleOwner(Lifecycle.State.CREATED, TestCoroutineDispatcher())
         runBlocking {
             // TODO guarantee later execution
             val action = owner.lifecycleScope.async {
                 throw RuntimeException("foo")
             }
             withContext(Dispatchers.Main) {
-                owner.setState(Lifecycle.State.STARTED)
+                owner.currentState = Lifecycle.State.STARTED
             }
             action.join()
             assertThat(action.getCompletionExceptionOrNull()).hasMessageThat().isSameInstanceAs(
@@ -139,7 +141,7 @@
 
     @Test
     fun runAnotherAfterCancellation_cancelOutside() {
-        val owner = FakeLifecycleOwner(Lifecycle.State.STARTED)
+        val owner = TestLifecycleOwner(Lifecycle.State.STARTED, TestCoroutineDispatcher())
         runBlocking {
             val action = owner.lifecycleScope.async {
                 delay(20000)
@@ -156,7 +158,7 @@
 
     @Test
     fun runAnotherAfterCancellation_cancelInside() {
-        val owner = FakeLifecycleOwner(Lifecycle.State.STARTED)
+        val owner = TestLifecycleOwner(Lifecycle.State.STARTED, TestCoroutineDispatcher())
         runBlocking {
             val action = owner.lifecycleScope.async {
                 throw CancellationException("")
@@ -172,7 +174,7 @@
 
     @Test
     fun runAnotherAfterFailure() {
-        val owner = FakeLifecycleOwner(Lifecycle.State.STARTED)
+        val owner = TestLifecycleOwner(Lifecycle.State.STARTED, TestCoroutineDispatcher())
         runBlocking {
             val action = owner.lifecycleScope.async {
                 throw IllegalArgumentException("why not ?")
diff --git a/lifecycle/lifecycle-livedata-core-ktx/build.gradle b/lifecycle/lifecycle-livedata-core-ktx/build.gradle
index d9366f6..61f7450 100644
--- a/lifecycle/lifecycle-livedata-core-ktx/build.gradle
+++ b/lifecycle/lifecycle-livedata-core-ktx/build.gradle
@@ -38,6 +38,8 @@
     api(KOTLIN_STDLIB)
     testImplementation(project(":lifecycle:lifecycle-runtime"))
     testImplementation("androidx.arch.core:core-testing:2.1.0")
+    testImplementation(project(":lifecycle:lifecycle-runtime-testing"))
+    testImplementation(KOTLIN_COROUTINES_TEST)
     testImplementation(JUNIT)
     testImplementation(TRUTH)
 }
diff --git a/lifecycle/lifecycle-livedata-core-ktx/src/test/java/androidx/lifecycle/LiveDataTest.kt b/lifecycle/lifecycle-livedata-core-ktx/src/test/java/androidx/lifecycle/LiveDataTest.kt
index aa0c1e2..d777ee7 100644
--- a/lifecycle/lifecycle-livedata-core-ktx/src/test/java/androidx/lifecycle/LiveDataTest.kt
+++ b/lifecycle/lifecycle-livedata-core-ktx/src/test/java/androidx/lifecycle/LiveDataTest.kt
@@ -17,7 +17,10 @@
 package androidx.lifecycle
 
 import androidx.arch.core.executor.testing.InstantTaskExecutorRule
+import androidx.lifecycle.testing.TestLifecycleOwner
 import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.TestCoroutineDispatcher
 import org.junit.Rule
 import org.junit.Test
 
@@ -26,15 +29,10 @@
     @get:Rule
     val mInstantTaskExecutorRule = InstantTaskExecutorRule()
 
+    @ExperimentalCoroutinesApi
     @Test
     fun observe() {
-        val lifecycleOwner = object : LifecycleOwner {
-            private val registry = LifecycleRegistry(this).apply {
-                currentState = Lifecycle.State.STARTED
-            }
-
-            override fun getLifecycle() = registry
-        }
+        val lifecycleOwner = TestLifecycleOwner(coroutineDispatcher = TestCoroutineDispatcher())
 
         val liveData = MutableLiveData<String>()
         var value = ""
diff --git a/lifecycle/lifecycle-livedata-core/build.gradle b/lifecycle/lifecycle-livedata-core/build.gradle
index 8b6c173..d8ba787 100644
--- a/lifecycle/lifecycle-livedata-core/build.gradle
+++ b/lifecycle/lifecycle-livedata-core/build.gradle
@@ -39,6 +39,8 @@
 
     testImplementation(project(":lifecycle:lifecycle-runtime"))
     testImplementation("androidx.arch.core:core-testing:2.1.0")
+    testImplementation(project(":lifecycle:lifecycle-runtime-testing"))
+    testImplementation(KOTLIN_COROUTINES_TEST)
     testImplementation(JUNIT)
     testImplementation(MOCKITO_CORE)
 }
diff --git a/lifecycle/lifecycle-livedata-core/src/test/java/androidx/lifecycle/LiveDataTest.java b/lifecycle/lifecycle-livedata-core/src/test/java/androidx/lifecycle/LiveDataTest.java
index c4c32ae..d7ba092 100644
--- a/lifecycle/lifecycle-livedata-core/src/test/java/androidx/lifecycle/LiveDataTest.java
+++ b/lifecycle/lifecycle-livedata-core/src/test/java/androidx/lifecycle/LiveDataTest.java
@@ -40,6 +40,7 @@
 import androidx.annotation.Nullable;
 import androidx.arch.core.executor.ArchTaskExecutor;
 import androidx.arch.core.executor.testing.InstantTaskExecutorRule;
+import androidx.lifecycle.testing.TestLifecycleOwner;
 
 import org.junit.After;
 import org.junit.Before;
@@ -51,6 +52,8 @@
 import org.mockito.InOrder;
 import org.mockito.Mockito;
 
+import kotlinx.coroutines.test.TestCoroutineDispatcher;
+
 @SuppressWarnings({"unchecked"})
 @RunWith(JUnit4.class)
 public class LiveDataTest {
@@ -61,11 +64,9 @@
     private PublicLiveData<String> mLiveData;
     private MethodExec mActiveObserversChanged;
 
-    private LifecycleOwner mOwner;
-    private LifecycleRegistry mRegistry;
+    private TestLifecycleOwner mOwner;
 
-    private LifecycleOwner mOwner2;
-    private LifecycleRegistry mRegistry2;
+    private TestLifecycleOwner mOwner2;
 
     private LifecycleOwner mOwner3;
     private Lifecycle mLifecycle3;
@@ -84,13 +85,11 @@
         mActiveObserversChanged = mock(MethodExec.class);
         mLiveData.activeObserversChanged = mActiveObserversChanged;
 
-        mOwner = mock(LifecycleOwner.class);
-        mRegistry = new LifecycleRegistry(mOwner);
-        when(mOwner.getLifecycle()).thenReturn(mRegistry);
+        mOwner = new TestLifecycleOwner(Lifecycle.State.INITIALIZED,
+                new TestCoroutineDispatcher());
 
-        mOwner2 = mock(LifecycleOwner.class);
-        mRegistry2 = new LifecycleRegistry(mOwner2);
-        when(mOwner2.getLifecycle()).thenReturn(mRegistry2);
+        mOwner2 = new TestLifecycleOwner(Lifecycle.State.INITIALIZED,
+                new TestCoroutineDispatcher());
 
         mInObserver = false;
     }
@@ -137,18 +136,18 @@
         assertThat(mLiveData.hasObservers(), is(true));
         assertThat(mLiveData.hasActiveObservers(), is(false));
 
-        mRegistry.handleLifecycleEvent(ON_START);
+        mOwner.handleLifecycleEvent(ON_START);
         verify(mActiveObserversChanged).onCall(true);
         assertThat(mLiveData.hasActiveObservers(), is(true));
         reset(mActiveObserversChanged);
 
-        mRegistry.handleLifecycleEvent(ON_STOP);
+        mOwner.handleLifecycleEvent(ON_STOP);
         verify(mActiveObserversChanged).onCall(false);
         assertThat(mLiveData.hasActiveObservers(), is(false));
         assertThat(mLiveData.hasObservers(), is(true));
 
         reset(mActiveObserversChanged);
-        mRegistry.handleLifecycleEvent(ON_START);
+        mOwner.handleLifecycleEvent(ON_START);
         verify(mActiveObserversChanged).onCall(true);
         assertThat(mLiveData.hasActiveObservers(), is(true));
         assertThat(mLiveData.hasObservers(), is(true));
@@ -179,7 +178,7 @@
         assertThat(mLiveData.hasObservers(), is(true));
         verify(mActiveObserversChanged, never()).onCall(anyBoolean());
 
-        mRegistry.handleLifecycleEvent(ON_START);
+        mOwner.handleLifecycleEvent(ON_START);
         verify(mActiveObserversChanged).onCall(true);
         mLiveData.setValue("a");
         verify(o1).onChanged("a");
@@ -188,7 +187,7 @@
         mLiveData.removeObservers(mOwner);
 
         assertThat(mLiveData.hasObservers(), is(false));
-        assertThat(mRegistry.getObserverCount(), is(0));
+        assertThat(mOwner.getObserverCount(), is(0));
     }
 
     @Test
@@ -212,14 +211,14 @@
     public void testRemoveDestroyedObserver() {
         Observer<String> observer = (Observer<String>) mock(Observer.class);
         mLiveData.observe(mOwner, observer);
-        mRegistry.handleLifecycleEvent(ON_START);
+        mOwner.handleLifecycleEvent(ON_START);
         verify(mActiveObserversChanged).onCall(true);
         assertThat(mLiveData.hasObservers(), is(true));
         assertThat(mLiveData.hasActiveObservers(), is(true));
 
         reset(mActiveObserversChanged);
 
-        mRegistry.handleLifecycleEvent(ON_DESTROY);
+        mOwner.handleLifecycleEvent(ON_DESTROY);
         assertThat(mLiveData.hasObservers(), is(false));
         assertThat(mLiveData.hasActiveObservers(), is(false));
         verify(mActiveObserversChanged).onCall(false);
@@ -228,7 +227,7 @@
     @Test
     public void testInactiveRegistry() {
         Observer<String> observer = (Observer<String>) mock(Observer.class);
-        mRegistry.handleLifecycleEvent(ON_DESTROY);
+        mOwner.handleLifecycleEvent(ON_DESTROY);
         mLiveData.observe(mOwner, observer);
         assertThat(mLiveData.hasObservers(), is(false));
     }
@@ -236,57 +235,57 @@
     @Test
     public void testNotifyActiveInactive() {
         Observer<String> observer = (Observer<String>) mock(Observer.class);
-        mRegistry.handleLifecycleEvent(ON_CREATE);
+        mOwner.handleLifecycleEvent(ON_CREATE);
         mLiveData.observe(mOwner, observer);
         mLiveData.setValue("a");
         verify(observer, never()).onChanged(anyString());
-        mRegistry.handleLifecycleEvent(ON_START);
+        mOwner.handleLifecycleEvent(ON_START);
         verify(observer).onChanged("a");
 
         mLiveData.setValue("b");
         verify(observer).onChanged("b");
 
-        mRegistry.handleLifecycleEvent(ON_STOP);
+        mOwner.handleLifecycleEvent(ON_STOP);
         mLiveData.setValue("c");
         verify(observer, never()).onChanged("c");
 
-        mRegistry.handleLifecycleEvent(ON_START);
+        mOwner.handleLifecycleEvent(ON_START);
         verify(observer).onChanged("c");
 
         reset(observer);
-        mRegistry.handleLifecycleEvent(ON_STOP);
-        mRegistry.handleLifecycleEvent(ON_START);
+        mOwner.handleLifecycleEvent(ON_STOP);
+        mOwner.handleLifecycleEvent(ON_START);
         verify(observer, never()).onChanged(anyString());
     }
 
     @Test
     public void testStopObservingOwner_onDestroy() {
         Observer<String> observer = (Observer<String>) mock(Observer.class);
-        mRegistry.handleLifecycleEvent(ON_CREATE);
+        mOwner.handleLifecycleEvent(ON_CREATE);
         mLiveData.observe(mOwner, observer);
-        assertThat(mRegistry.getObserverCount(), is(1));
-        mRegistry.handleLifecycleEvent(ON_DESTROY);
-        assertThat(mRegistry.getObserverCount(), is(0));
+        assertThat(mOwner.getObserverCount(), is(1));
+        mOwner.handleLifecycleEvent(ON_DESTROY);
+        assertThat(mOwner.getObserverCount(), is(0));
     }
 
     @Test
     public void testStopObservingOwner_onStopObserving() {
         Observer<String> observer = (Observer<String>) mock(Observer.class);
-        mRegistry.handleLifecycleEvent(ON_CREATE);
+        mOwner.handleLifecycleEvent(ON_CREATE);
         mLiveData.observe(mOwner, observer);
-        assertThat(mRegistry.getObserverCount(), is(1));
+        assertThat(mOwner.getObserverCount(), is(1));
 
         mLiveData.removeObserver(observer);
-        assertThat(mRegistry.getObserverCount(), is(0));
+        assertThat(mOwner.getObserverCount(), is(0));
     }
 
     @Test
     public void testActiveChangeInCallback() {
-        mRegistry.handleLifecycleEvent(ON_START);
+        mOwner.handleLifecycleEvent(ON_START);
         Observer<String> observer1 = spy(new Observer<String>() {
             @Override
             public void onChanged(@Nullable String s) {
-                mRegistry.handleLifecycleEvent(ON_STOP);
+                mOwner.handleLifecycleEvent(ON_STOP);
                 assertThat(mLiveData.hasObservers(), is(true));
                 assertThat(mLiveData.hasActiveObservers(), is(false));
             }
@@ -308,7 +307,7 @@
             public void onChanged(@Nullable String s) {
                 assertThat(mInObserver, is(false));
                 mInObserver = true;
-                mRegistry.handleLifecycleEvent(ON_START);
+                mOwner.handleLifecycleEvent(ON_START);
                 assertThat(mLiveData.hasActiveObservers(), is(true));
                 mInObserver = false;
             }
@@ -325,7 +324,7 @@
 
     @Test
     public void testObserverRemovalInCallback() {
-        mRegistry.handleLifecycleEvent(ON_START);
+        mOwner.handleLifecycleEvent(ON_START);
         Observer<String> observer = spy(new Observer<String>() {
             @Override
             public void onChanged(@Nullable String s) {
@@ -342,7 +341,7 @@
 
     @Test
     public void testObserverAdditionInCallback() {
-        mRegistry.handleLifecycleEvent(ON_START);
+        mOwner.handleLifecycleEvent(ON_START);
         final Observer observer2 = spy(new FailReentranceObserver());
         Observer<String> observer1 = spy(new Observer<String>() {
             @Override
@@ -381,7 +380,7 @@
 
     @Test
     public void testSetValueDuringSetValue() {
-        mRegistry.handleLifecycleEvent(ON_START);
+        mOwner.handleLifecycleEvent(ON_START);
         final Observer observer1 = spy(new Observer<String>() {
             @Override
             public void onChanged(String o) {
@@ -403,7 +402,7 @@
 
     @Test
     public void testRemoveDuringSetValue() {
-        mRegistry.handleLifecycleEvent(ON_START);
+        mOwner.handleLifecycleEvent(ON_START);
         final Observer observer1 = spy(new Observer<String>() {
             @Override
             public void onChanged(String o) {
@@ -419,8 +418,8 @@
 
     @Test
     public void testDataChangeDuringStateChange() {
-        mRegistry.handleLifecycleEvent(ON_START);
-        mRegistry.addObserver(new LifecycleObserver() {
+        mOwner.handleLifecycleEvent(ON_START);
+        mOwner.getLifecycle().addObserver(new LifecycleObserver() {
             @OnLifecycleEvent(ON_STOP)
             public void onStop() {
                 // change data in onStop, observer should not be called!
@@ -431,32 +430,32 @@
         mLiveData.setValue("a");
         mLiveData.observe(mOwner, observer);
         verify(observer).onChanged("a");
-        mRegistry.handleLifecycleEvent(ON_PAUSE);
-        mRegistry.handleLifecycleEvent(ON_STOP);
+        mOwner.handleLifecycleEvent(ON_PAUSE);
+        mOwner.handleLifecycleEvent(ON_STOP);
         verify(observer, never()).onChanged("b");
 
-        mRegistry.handleLifecycleEvent(ON_RESUME);
+        mOwner.handleLifecycleEvent(ON_RESUME);
         verify(observer).onChanged("b");
     }
 
     @Test
     public void testNotCallInactiveWithObserveForever() {
-        mRegistry.handleLifecycleEvent(ON_START);
+        mOwner.handleLifecycleEvent(ON_START);
         Observer<String> observer = (Observer<String>) mock(Observer.class);
         Observer<String> observer2 = (Observer<String>) mock(Observer.class);
         mLiveData.observe(mOwner, observer);
         mLiveData.observeForever(observer2);
         verify(mActiveObserversChanged).onCall(true);
         reset(mActiveObserversChanged);
-        mRegistry.handleLifecycleEvent(ON_STOP);
+        mOwner.handleLifecycleEvent(ON_STOP);
         verify(mActiveObserversChanged, never()).onCall(anyBoolean());
-        mRegistry.handleLifecycleEvent(ON_START);
+        mOwner.handleLifecycleEvent(ON_START);
         verify(mActiveObserversChanged, never()).onCall(anyBoolean());
     }
 
     @Test
     public void testRemoveDuringAddition() {
-        mRegistry.handleLifecycleEvent(ON_START);
+        mOwner.handleLifecycleEvent(ON_START);
         mLiveData.setValue("bla");
         mLiveData.observeForever(new Observer<String>() {
             @Override
@@ -480,7 +479,7 @@
                 mLiveData.removeObserver(this);
             }
         });
-        mRegistry.handleLifecycleEvent(ON_RESUME);
+        mOwner.handleLifecycleEvent(ON_RESUME);
         assertThat(mLiveData.hasActiveObservers(), is(false));
         InOrder inOrder = Mockito.inOrder(mActiveObserversChanged);
         inOrder.verify(mActiveObserversChanged).onCall(true);
@@ -506,8 +505,8 @@
         mLiveData.observe(mOwner, observer1);
         mLiveData.observe(mOwner2, observer2);
 
-        mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START);
-        mRegistry2.handleLifecycleEvent(Lifecycle.Event.ON_START);
+        mOwner.handleLifecycleEvent(Lifecycle.Event.ON_START);
+        mOwner2.handleLifecycleEvent(Lifecycle.Event.ON_START);
 
         mLiveData.setValue("1");
 
@@ -523,7 +522,7 @@
         mLiveData.observe(mOwner, observer1);
         mLiveData.observe(mOwner2, observer2);
 
-        mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START);
+        mOwner.handleLifecycleEvent(Lifecycle.Event.ON_START);
 
         mLiveData.setValue("1");
 
@@ -541,8 +540,8 @@
 
         mLiveData.setValue("1");
 
-        mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START);
-        mRegistry2.handleLifecycleEvent(Lifecycle.Event.ON_START);
+        mOwner.handleLifecycleEvent(Lifecycle.Event.ON_START);
+        mOwner2.handleLifecycleEvent(Lifecycle.Event.ON_START);
 
         verify(observer1).onChanged("1");
         verify(observer1).onChanged("1");
@@ -558,7 +557,7 @@
 
         mLiveData.setValue("1");
 
-        mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START);
+        mOwner.handleLifecycleEvent(Lifecycle.Event.ON_START);
 
         verify(observer1).onChanged("1");
         verify(observer2, never()).onChanged(anyString());
@@ -572,7 +571,7 @@
         mLiveData.observe(mOwner, observer1);
         mLiveData.observe(mOwner2, observer2);
 
-        mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START);
+        mOwner.handleLifecycleEvent(Lifecycle.Event.ON_START);
 
         verify(mActiveObserversChanged).onCall(true);
     }
@@ -585,13 +584,13 @@
         mLiveData.observe(mOwner, observer1);
         mLiveData.observe(mOwner2, observer2);
 
-        mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START);
-        mRegistry2.handleLifecycleEvent(Lifecycle.Event.ON_START);
+        mOwner.handleLifecycleEvent(Lifecycle.Event.ON_START);
+        mOwner2.handleLifecycleEvent(Lifecycle.Event.ON_START);
 
         verify(mActiveObserversChanged).onCall(true);
 
         reset(mActiveObserversChanged);
-        mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_STOP);
+        mOwner.handleLifecycleEvent(Lifecycle.Event.ON_STOP);
 
         verify(mActiveObserversChanged, never()).onCall(anyBoolean());
     }
@@ -806,7 +805,7 @@
     public void initialValue() {
         MutableLiveData<String> mutableLiveData = new MutableLiveData<>("foo");
         Observer<String> observer = mock(Observer.class);
-        mRegistry.handleLifecycleEvent(ON_START);
+        mOwner.handleLifecycleEvent(ON_START);
         mutableLiveData.observe(mOwner, observer);
         verify(observer).onChanged("foo");
     }
diff --git a/lifecycle/lifecycle-livedata-core/src/test/java/androidx/lifecycle/ThreadedLiveDataTest.java b/lifecycle/lifecycle-livedata-core/src/test/java/androidx/lifecycle/ThreadedLiveDataTest.java
index 19dcd21..d667a9e 100644
--- a/lifecycle/lifecycle-livedata-core/src/test/java/androidx/lifecycle/ThreadedLiveDataTest.java
+++ b/lifecycle/lifecycle-livedata-core/src/test/java/androidx/lifecycle/ThreadedLiveDataTest.java
@@ -20,12 +20,11 @@
 
 import static org.hamcrest.CoreMatchers.is;
 import static org.hamcrest.MatcherAssert.assertThat;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
 
 import androidx.annotation.Nullable;
 import androidx.arch.core.executor.JunitTaskExecutorRule;
 import androidx.arch.core.executor.TaskExecutor;
+import androidx.lifecycle.testing.TestLifecycleOwner;
 
 import org.junit.Before;
 import org.junit.Rule;
@@ -36,6 +35,8 @@
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 
+import kotlinx.coroutines.test.TestCoroutineDispatcher;
+
 @RunWith(JUnit4.class)
 public class ThreadedLiveDataTest {
 
@@ -45,15 +46,13 @@
     public JunitTaskExecutorRule mTaskExecutorRule = new JunitTaskExecutorRule(1, false);
 
     private LiveData<String> mLiveData;
-    private LifecycleOwner mLifecycleOwner;
-    private LifecycleRegistry mRegistry;
+    private TestLifecycleOwner mLifecycleOwner;
 
     @Before
     public void init() {
         mLiveData = new MutableLiveData<>();
-        mLifecycleOwner = mock(LifecycleOwner.class);
-        mRegistry = new LifecycleRegistry(mLifecycleOwner);
-        when(mLifecycleOwner.getLifecycle()).thenReturn(mRegistry);
+        mLifecycleOwner = new TestLifecycleOwner(Lifecycle.State.INITIALIZED,
+                new TestCoroutineDispatcher());
     }
 
     @Test
@@ -74,7 +73,7 @@
         taskExecutor.executeOnMainThread(new Runnable() {
             @Override
             public void run() {
-                mRegistry.handleLifecycleEvent(ON_START);
+                mLifecycleOwner.handleLifecycleEvent(ON_START);
                 mLiveData.observe(mLifecycleOwner, observer);
                 final CountDownLatch latch = new CountDownLatch(1);
                 taskExecutor.executeOnDiskIO(new Runnable() {
diff --git a/lifecycle/lifecycle-livedata-ktx/build.gradle b/lifecycle/lifecycle-livedata-ktx/build.gradle
index 88acb8f..85170c5 100644
--- a/lifecycle/lifecycle-livedata-ktx/build.gradle
+++ b/lifecycle/lifecycle-livedata-ktx/build.gradle
@@ -42,7 +42,7 @@
     api(project(":lifecycle:lifecycle-livedata-core-ktx"))
     api(KOTLIN_STDLIB)
     api(KOTLIN_COROUTINES_CORE)
-    testImplementation(project(":lifecycle:lifecycle-runtime"))
+    testImplementation(project(":lifecycle:lifecycle-runtime-testing"))
     testImplementation("androidx.arch.core:core-testing:2.1.0")
     testImplementation(JUNIT)
     testImplementation(TRUTH)
diff --git a/lifecycle/lifecycle-livedata-ktx/src/test/java/androidx/lifecycle/TransformationsTest.kt b/lifecycle/lifecycle-livedata-ktx/src/test/java/androidx/lifecycle/TransformationsTest.kt
index 9f8bb0d..82b03da 100644
--- a/lifecycle/lifecycle-livedata-ktx/src/test/java/androidx/lifecycle/TransformationsTest.kt
+++ b/lifecycle/lifecycle-livedata-ktx/src/test/java/androidx/lifecycle/TransformationsTest.kt
@@ -17,21 +17,21 @@
 package androidx.lifecycle
 
 import androidx.arch.core.executor.testing.InstantTaskExecutorRule
+import androidx.lifecycle.testing.TestLifecycleOwner
 import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.TestCoroutineDispatcher
 import org.junit.Rule
 import org.junit.Test
 
+@ExperimentalCoroutinesApi
 class TransformationsTest {
 
     @get:Rule
     val mInstantTaskExecutorRule = InstantTaskExecutorRule()
 
-    private val lifecycleOwner = object : LifecycleOwner {
-        private val registry = LifecycleRegistry(this).apply {
-            currentState = Lifecycle.State.STARTED
-        }
-        override fun getLifecycle() = registry
-    }
+    private val lifecycleOwner = TestLifecycleOwner(
+        coroutineDispatcher = TestCoroutineDispatcher())
 
     @Test fun map() {
         val source = MutableLiveData<String>()
diff --git a/lifecycle/lifecycle-livedata/build.gradle b/lifecycle/lifecycle-livedata/build.gradle
index fdd20bf..b43db3a 100644
--- a/lifecycle/lifecycle-livedata/build.gradle
+++ b/lifecycle/lifecycle-livedata/build.gradle
@@ -30,8 +30,9 @@
     api("androidx.arch.core:core-runtime:2.1.0")
     api(project(":lifecycle:lifecycle-livedata-core"))
 
-    testImplementation(project(":lifecycle:lifecycle-runtime"))
+    testImplementation(project(":lifecycle:lifecycle-runtime-testing"))
     testImplementation("androidx.arch.core:core-testing:2.1.0")
+    testImplementation(KOTLIN_COROUTINES_TEST)
     testImplementation(JUNIT)
     testImplementation(MOCKITO_CORE)
 }
diff --git a/lifecycle/lifecycle-livedata/src/test/java/androidx/lifecycle/ComputableLiveDataTest.java b/lifecycle/lifecycle-livedata/src/test/java/androidx/lifecycle/ComputableLiveDataTest.java
index 391cbca..fdc0ae7d 100644
--- a/lifecycle/lifecycle-livedata/src/test/java/androidx/lifecycle/ComputableLiveDataTest.java
+++ b/lifecycle/lifecycle-livedata/src/test/java/androidx/lifecycle/ComputableLiveDataTest.java
@@ -32,6 +32,7 @@
 import androidx.arch.core.executor.ArchTaskExecutor;
 import androidx.arch.core.executor.TaskExecutor;
 import androidx.arch.core.executor.TaskExecutorWithFakeMainThread;
+import androidx.lifecycle.testing.TestLifecycleOwner;
 import androidx.lifecycle.util.InstantTaskExecutor;
 
 import org.junit.After;
@@ -47,6 +48,8 @@
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicInteger;
 
+import kotlinx.coroutines.test.TestCoroutineDispatcher;
+
 @RunWith(JUnit4.class)
 public class ComputableLiveDataTest {
     private TaskExecutor mTaskExecutor;
@@ -54,7 +57,8 @@
 
     @Before
     public void setup() {
-        mLifecycleOwner = new TestLifecycleOwner();
+        mLifecycleOwner = new TestLifecycleOwner(Lifecycle.State.INITIALIZED,
+                new TestCoroutineDispatcher());
     }
 
     @Before
@@ -135,7 +139,7 @@
     @Test
     public void addingObserverShouldTriggerAComputation() {
         TestComputable computable = new TestComputable(1);
-        mLifecycleOwner.handleEvent(Lifecycle.Event.ON_CREATE);
+        mLifecycleOwner.handleLifecycleEvent(Lifecycle.Event.ON_CREATE);
         final AtomicInteger mValue = new AtomicInteger(-1);
         computable.getLiveData().observe(mLifecycleOwner, new Observer<Integer>() {
             @Override
@@ -146,7 +150,7 @@
         });
         verify(mTaskExecutor, never()).executeOnDiskIO(any(Runnable.class));
         assertThat(mValue.get(), is(-1));
-        mLifecycleOwner.handleEvent(Lifecycle.Event.ON_START);
+        mLifecycleOwner.handleLifecycleEvent(Lifecycle.Event.ON_START);
         verify(mTaskExecutor).executeOnDiskIO(computable.mRefreshRunnable);
         assertThat(mValue.get(), is(1));
     }
@@ -155,7 +159,7 @@
     public void customExecutor() {
         Executor customExecutor = mock(Executor.class);
         TestComputable computable = new TestComputable(customExecutor, 1);
-        mLifecycleOwner.handleEvent(Lifecycle.Event.ON_CREATE);
+        mLifecycleOwner.handleLifecycleEvent(Lifecycle.Event.ON_CREATE);
         computable.getLiveData().observe(mLifecycleOwner, new Observer<Integer>() {
             @Override
             public void onChanged(@Nullable Integer integer) {
@@ -165,7 +169,7 @@
         verify(mTaskExecutor, never()).executeOnDiskIO(any(Runnable.class));
         verify(customExecutor, never()).execute(any(Runnable.class));
 
-        mLifecycleOwner.handleEvent(Lifecycle.Event.ON_START);
+        mLifecycleOwner.handleLifecycleEvent(Lifecycle.Event.ON_START);
 
         verify(mTaskExecutor, never()).executeOnDiskIO(computable.mRefreshRunnable);
         verify(customExecutor).execute(computable.mRefreshRunnable);
@@ -174,7 +178,7 @@
     @Test
     public void invalidationShouldNotReTriggerComputationIfObserverIsInActive() {
         TestComputable computable = new TestComputable(1, 2);
-        mLifecycleOwner.handleEvent(Lifecycle.Event.ON_START);
+        mLifecycleOwner.handleLifecycleEvent(Lifecycle.Event.ON_START);
         final AtomicInteger mValue = new AtomicInteger(-1);
         computable.getLiveData().observe(mLifecycleOwner, new Observer<Integer>() {
             @Override
@@ -184,7 +188,7 @@
             }
         });
         assertThat(mValue.get(), is(1));
-        mLifecycleOwner.handleEvent(Lifecycle.Event.ON_STOP);
+        mLifecycleOwner.handleLifecycleEvent(Lifecycle.Event.ON_STOP);
         computable.invalidate();
         reset(mTaskExecutor);
         verify(mTaskExecutor, never()).executeOnDiskIO(computable.mRefreshRunnable);
@@ -194,7 +198,7 @@
     @Test
     public void invalidationShouldReTriggerQueryIfObserverIsActive() {
         TestComputable computable = new TestComputable(1, 2);
-        mLifecycleOwner.handleEvent(Lifecycle.Event.ON_START);
+        mLifecycleOwner.handleLifecycleEvent(Lifecycle.Event.ON_START);
         final AtomicInteger mValue = new AtomicInteger(-1);
         computable.getLiveData().observe(mLifecycleOwner, new Observer<Integer>() {
             @Override
@@ -226,21 +230,4 @@
             return mValues[mValueCounter.getAndIncrement()];
         }
     }
-
-    static class TestLifecycleOwner implements LifecycleOwner {
-        private LifecycleRegistry mLifecycle;
-
-        TestLifecycleOwner() {
-            mLifecycle = new LifecycleRegistry(this);
-        }
-
-        @Override
-        public Lifecycle getLifecycle() {
-            return mLifecycle;
-        }
-
-        void handleEvent(Lifecycle.Event event) {
-            mLifecycle.handleLifecycleEvent(event);
-        }
-    }
 }
diff --git a/lifecycle/lifecycle-livedata/src/test/java/androidx/lifecycle/MediatorLiveDataTest.java b/lifecycle/lifecycle-livedata/src/test/java/androidx/lifecycle/MediatorLiveDataTest.java
index bb57185..9155a79 100644
--- a/lifecycle/lifecycle-livedata/src/test/java/androidx/lifecycle/MediatorLiveDataTest.java
+++ b/lifecycle/lifecycle-livedata/src/test/java/androidx/lifecycle/MediatorLiveDataTest.java
@@ -23,11 +23,11 @@
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.reset;
 import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
 
 import androidx.annotation.Nullable;
 import androidx.arch.core.executor.ArchTaskExecutor;
 import androidx.arch.core.executor.testing.InstantTaskExecutorRule;
+import androidx.lifecycle.testing.TestLifecycleOwner;
 import androidx.lifecycle.util.InstantTaskExecutor;
 
 import org.junit.Before;
@@ -36,6 +36,8 @@
 import org.junit.runner.RunWith;
 import org.junit.runners.JUnit4;
 
+import kotlinx.coroutines.test.TestCoroutineDispatcher;
+
 @SuppressWarnings("unchecked")
 @RunWith(JUnit4.class)
 public class MediatorLiveDataTest {
@@ -43,17 +45,15 @@
     @Rule
     public InstantTaskExecutorRule mInstantTaskExecutorRule = new InstantTaskExecutorRule();
 
-    private LifecycleOwner mOwner;
-    private LifecycleRegistry mRegistry;
+    private TestLifecycleOwner mOwner;
     private MediatorLiveData<String> mMediator;
     private LiveData<String> mSource;
     private boolean mSourceActive;
 
     @Before
     public void setup() {
-        mOwner = mock(LifecycleOwner.class);
-        mRegistry = new LifecycleRegistry(mOwner);
-        when(mOwner.getLifecycle()).thenReturn(mRegistry);
+        mOwner = new TestLifecycleOwner(Lifecycle.State.STARTED,
+                new TestCoroutineDispatcher());
         mMediator = new MediatorLiveData<>();
         mSource = new LiveData<String>() {
             @Override
@@ -68,8 +68,6 @@
         };
         mSourceActive = false;
         mMediator.observe(mOwner, mock(Observer.class));
-        mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE);
-        mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START);
     }
 
     @Before
@@ -83,7 +81,7 @@
         mMediator.addSource(mSource, observer);
         mSource.setValue("flatfoot");
         verify(observer).onChanged("flatfoot");
-        mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_STOP);
+        mOwner.handleLifecycleEvent(Lifecycle.Event.ON_STOP);
         reset(observer);
         verify(observer, never()).onChanged(any());
     }
@@ -95,10 +93,10 @@
         mMediator.observe(mOwner, mock(Observer.class));
         mSource.setValue("one");
         verify(observer).onChanged("one");
-        mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_STOP);
+        mOwner.handleLifecycleEvent(Lifecycle.Event.ON_STOP);
         reset(observer);
         mSource.setValue("flatfoot");
-        mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START);
+        mOwner.handleLifecycleEvent(Lifecycle.Event.ON_START);
         verify(observer).onChanged("flatfoot");
     }
 
@@ -114,11 +112,11 @@
     @Test
     public void testAddSourceToInActive() {
         mSource.setValue("flatfoot");
-        mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_STOP);
+        mOwner.handleLifecycleEvent(Lifecycle.Event.ON_STOP);
         Observer observer = mock(Observer.class);
         mMediator.addSource(mSource, observer);
         verify(observer, never()).onChanged(any());
-        mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START);
+        mOwner.handleLifecycleEvent(Lifecycle.Event.ON_START);
         verify(observer).onChanged("flatfoot");
     }
 
@@ -139,9 +137,9 @@
         Observer observer = mock(Observer.class);
         mMediator.addSource(mSource, observer);
         assertThat(mSourceActive, is(true));
-        mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_STOP);
+        mOwner.handleLifecycleEvent(Lifecycle.Event.ON_STOP);
         assertThat(mSourceActive, is(false));
-        mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START);
+        mOwner.handleLifecycleEvent(Lifecycle.Event.ON_START);
         assertThat(mSourceActive, is(true));
     }
 
@@ -154,8 +152,8 @@
         Observer observer = mock(Observer.class);
         mMediator.addSource(mSource, observer);
         assertThat(mSource.hasObservers(), is(true));
-        mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_STOP);
-        mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY);
+        mOwner.handleLifecycleEvent(Lifecycle.Event.ON_STOP);
+        mOwner.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY);
         mMediator = null;
         assertThat(mSource.hasObservers(), is(false));
     }
@@ -175,7 +173,7 @@
         verify(observer1, never()).onChanged(any());
         verify(observer2).onChanged(1703);
         reset(observer1, observer2);
-        mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_STOP);
+        mOwner.handleLifecycleEvent(Lifecycle.Event.ON_STOP);
         mSource.setValue("failure");
         source2.setValue(0);
         verify(observer1, never()).onChanged(any());
@@ -191,7 +189,7 @@
         // because if it is a last iteration, then next() wouldn't be called.
         // And the last: an order of an iteration over sources is not defined,
         // so I have to call it remove operation  from all observers.
-        mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_STOP);
+        mOwner.handleLifecycleEvent(Lifecycle.Event.ON_STOP);
         Observer<String> removingObserver = new Observer<String>() {
             @Override
             public void onChanged(@Nullable String s) {
@@ -203,7 +201,7 @@
         source2.setValue("nana");
         mMediator.addSource(source2, removingObserver);
         mSource.setValue("petjack");
-        mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START);
+        mOwner.handleLifecycleEvent(Lifecycle.Event.ON_START);
     }
 
     @Test(expected = IllegalArgumentException.class)
@@ -222,7 +220,7 @@
 
     @Test
     public void addSourceDuringOnActive() {
-        mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_STOP);
+        mOwner.handleLifecycleEvent(Lifecycle.Event.ON_STOP);
         mSource.setValue("a");
         mMediator.addSource(mSource, new Observer<String>() {
             @Override
@@ -237,7 +235,7 @@
                 });
             }
         });
-        mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START);
+        mOwner.handleLifecycleEvent(Lifecycle.Event.ON_START);
         assertThat(mMediator.getValue(), is("c"));
     }
 
diff --git a/lifecycle/lifecycle-livedata/src/test/java/androidx/lifecycle/TransformationsTest.java b/lifecycle/lifecycle-livedata/src/test/java/androidx/lifecycle/TransformationsTest.java
index 8ac204e..5489f33 100644
--- a/lifecycle/lifecycle-livedata/src/test/java/androidx/lifecycle/TransformationsTest.java
+++ b/lifecycle/lifecycle-livedata/src/test/java/androidx/lifecycle/TransformationsTest.java
@@ -25,11 +25,11 @@
 import static org.mockito.Mockito.only;
 import static org.mockito.Mockito.reset;
 import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
 
 import androidx.annotation.Nullable;
 import androidx.arch.core.executor.ArchTaskExecutor;
 import androidx.arch.core.util.Function;
+import androidx.lifecycle.testing.TestLifecycleOwner;
 import androidx.lifecycle.util.InstantTaskExecutor;
 
 import org.junit.Before;
@@ -37,11 +37,13 @@
 import org.junit.runner.RunWith;
 import org.junit.runners.JUnit4;
 
+import kotlinx.coroutines.test.TestCoroutineDispatcher;
+
 @SuppressWarnings("unchecked")
 @RunWith(JUnit4.class)
 public class TransformationsTest {
 
-    private LifecycleOwner mOwner;
+    private TestLifecycleOwner mOwner;
 
     @Before
     public void swapExecutorDelegate() {
@@ -50,11 +52,8 @@
 
     @Before
     public void setup() {
-        mOwner = mock(LifecycleOwner.class);
-        LifecycleRegistry registry = new LifecycleRegistry(mOwner);
-        when(mOwner.getLifecycle()).thenReturn(registry);
-        registry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE);
-        registry.handleLifecycleEvent(Lifecycle.Event.ON_START);
+        mOwner = new TestLifecycleOwner(Lifecycle.State.STARTED,
+                new TestCoroutineDispatcher());
     }
 
     @Test
diff --git a/lifecycle/lifecycle-reactivestreams-ktx/build.gradle b/lifecycle/lifecycle-reactivestreams-ktx/build.gradle
index 0faaa78..75015d5 100644
--- a/lifecycle/lifecycle-reactivestreams-ktx/build.gradle
+++ b/lifecycle/lifecycle-reactivestreams-ktx/build.gradle
@@ -33,6 +33,8 @@
   testImplementation(JUNIT)
   testImplementation(RX_JAVA)
   testImplementation(TRUTH)
+  testImplementation(KOTLIN_COROUTINES_TEST)
+  testImplementation(project(":lifecycle:lifecycle-runtime-testing"))
   testImplementation("androidx.arch.core:core-testing:2.1.0")
 }
 
diff --git a/lifecycle/lifecycle-reactivestreams-ktx/src/test/java/androidx/lifecycle/LiveDataReactiveStreamsTest.kt b/lifecycle/lifecycle-reactivestreams-ktx/src/test/java/androidx/lifecycle/LiveDataReactiveStreamsTest.kt
index ad3bdb2..3741dd0 100644
--- a/lifecycle/lifecycle-reactivestreams-ktx/src/test/java/androidx/lifecycle/LiveDataReactiveStreamsTest.kt
+++ b/lifecycle/lifecycle-reactivestreams-ktx/src/test/java/androidx/lifecycle/LiveDataReactiveStreamsTest.kt
@@ -17,9 +17,12 @@
 package androidx.lifecycle
 
 import androidx.arch.core.executor.testing.InstantTaskExecutorRule
+import androidx.lifecycle.testing.TestLifecycleOwner
 import com.google.common.truth.Truth.assertThat
 import io.reactivex.processors.PublishProcessor
 import io.reactivex.processors.ReplayProcessor
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.TestCoroutineDispatcher
 import org.junit.Before
 import org.junit.Rule
 import org.junit.Test
@@ -29,18 +32,9 @@
 
     private lateinit var lifecycleOwner: LifecycleOwner
 
+    @ExperimentalCoroutinesApi
     @Before fun init() {
-        lifecycleOwner = object : LifecycleOwner {
-            internal var registry = LifecycleRegistry(this)
-
-            init {
-                registry.handleLifecycleEvent(Lifecycle.Event.ON_RESUME)
-            }
-
-            override fun getLifecycle(): Lifecycle {
-                return registry
-            }
-        }
+        lifecycleOwner = TestLifecycleOwner(coroutineDispatcher = TestCoroutineDispatcher())
     }
 
     @Test fun convertsFromPublisher() {
diff --git a/lifecycle/lifecycle-reactivestreams/build.gradle b/lifecycle/lifecycle-reactivestreams/build.gradle
index 2dd9dd4..9b58227 100644
--- a/lifecycle/lifecycle-reactivestreams/build.gradle
+++ b/lifecycle/lifecycle-reactivestreams/build.gradle
@@ -37,6 +37,8 @@
 
     testImplementation(JUNIT)
     testImplementation(RX_JAVA)
+    testImplementation(KOTLIN_COROUTINES_TEST)
+    testImplementation(project(":lifecycle:lifecycle-runtime-testing"))
     testImplementation("androidx.arch.core:core-testing:2.1.0")
 }
 
diff --git a/lifecycle/lifecycle-reactivestreams/src/test/java/androidx/lifecycle/LiveDataReactiveStreamsTest.java b/lifecycle/lifecycle-reactivestreams/src/test/java/androidx/lifecycle/LiveDataReactiveStreamsTest.java
index ed792d2..02df611 100644
--- a/lifecycle/lifecycle-reactivestreams/src/test/java/androidx/lifecycle/LiveDataReactiveStreamsTest.java
+++ b/lifecycle/lifecycle-reactivestreams/src/test/java/androidx/lifecycle/LiveDataReactiveStreamsTest.java
@@ -23,6 +23,7 @@
 
 import androidx.annotation.Nullable;
 import androidx.arch.core.executor.testing.InstantTaskExecutorRule;
+import androidx.lifecycle.testing.TestLifecycleOwner;
 
 import org.junit.Before;
 import org.junit.Rule;
@@ -44,11 +45,12 @@
 import io.reactivex.processors.ReplayProcessor;
 import io.reactivex.schedulers.TestScheduler;
 import io.reactivex.subjects.AsyncSubject;
+import kotlinx.coroutines.test.TestCoroutineDispatcher;
 
 public class LiveDataReactiveStreamsTest {
     @Rule public final TestRule instantTaskExecutorRule = new InstantTaskExecutorRule();
 
-    private LifecycleOwner mLifecycleOwner;
+    private TestLifecycleOwner mLifecycleOwner;
 
     private final List<String> mLiveDataOutput = new ArrayList<>();
     private final Observer<String> mObserver = new Observer<String>() {
@@ -64,17 +66,8 @@
 
     @Before
     public void init() {
-        mLifecycleOwner = new LifecycleOwner() {
-            LifecycleRegistry mRegistry = new LifecycleRegistry(this);
-            {
-                mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_RESUME);
-            }
-
-            @Override
-            public Lifecycle getLifecycle() {
-                return mRegistry;
-            }
-        };
+        mLifecycleOwner = new TestLifecycleOwner(Lifecycle.State.RESUMED,
+                new TestCoroutineDispatcher());
     }
 
     @Test
diff --git a/loader/loader-ktx/build.gradle b/loader/loader-ktx/build.gradle
index 708edf6..5bc976a 100644
--- a/loader/loader-ktx/build.gradle
+++ b/loader/loader-ktx/build.gradle
@@ -41,7 +41,7 @@
     api(KOTLIN_STDLIB)
 
     androidTestImplementation(TRUTH)
-    androidTestImplementation("androidx.lifecycle:lifecycle-runtime:2.0.0")
+    androidTestImplementation(project(":lifecycle:lifecycle-runtime-testing"))
     androidTestImplementation(ANDROIDX_TEST_EXT_JUNIT)
     androidTestImplementation(ANDROIDX_TEST_CORE)
     androidTestImplementation(ANDROIDX_TEST_RUNNER)
diff --git a/loader/loader-ktx/src/androidTest/java/androidx/loader/app/LoaderManagerTest.kt b/loader/loader-ktx/src/androidTest/java/androidx/loader/app/LoaderManagerTest.kt
index ef302aa..809d8b8 100644
--- a/loader/loader-ktx/src/androidTest/java/androidx/loader/app/LoaderManagerTest.kt
+++ b/loader/loader-ktx/src/androidTest/java/androidx/loader/app/LoaderManagerTest.kt
@@ -17,7 +17,8 @@
 package androidx.loader.app
 
 import android.content.Context
-import androidx.loader.app.test.LoaderOwner
+import androidx.lifecycle.ViewModelStore
+import androidx.lifecycle.testing.TestLifecycleOwner
 import androidx.loader.content.Loader
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.LargeTest
@@ -38,7 +39,7 @@
 
     @Before
     fun setup() {
-        loaderManager = LoaderManager.getInstance(LoaderOwner())
+        loaderManager = LoaderManager.getInstance(TestLifecycleOwner(), ViewModelStore())
     }
 
     @Test
diff --git a/loader/loader-ktx/src/androidTest/java/androidx/loader/app/test/LoaderOwner.kt b/loader/loader-ktx/src/androidTest/java/androidx/loader/app/test/LoaderOwner.kt
deleted file mode 100644
index 7fb6a10..0000000
--- a/loader/loader-ktx/src/androidTest/java/androidx/loader/app/test/LoaderOwner.kt
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.loader.app.test
-
-import androidx.lifecycle.Lifecycle
-import androidx.lifecycle.LifecycleOwner
-import androidx.lifecycle.LifecycleRegistry
-import androidx.lifecycle.ViewModelStore
-import androidx.lifecycle.ViewModelStoreOwner
-
-class LoaderOwner : LifecycleOwner, ViewModelStoreOwner {
-
-    private val lifecycle = LifecycleRegistry(this)
-    private val viewModelStore = ViewModelStore()
-
-    init {
-        lifecycle.handleLifecycleEvent(Lifecycle.Event.ON_START)
-    }
-
-    override fun getLifecycle() = lifecycle
-
-    override fun getViewModelStore() = viewModelStore
-}
diff --git a/loader/loader/build.gradle b/loader/loader/build.gradle
index 4180c63..3b958cf 100644
--- a/loader/loader/build.gradle
+++ b/loader/loader/build.gradle
@@ -22,6 +22,7 @@
     implementation("androidx.collection:collection:1.0.0")
     implementation("androidx.lifecycle:lifecycle-livedata-core:2.0.0")
 
+    androidTestImplementation(project(":lifecycle:lifecycle-runtime-testing"))
     androidTestImplementation(ANDROIDX_TEST_EXT_JUNIT)
     androidTestImplementation(ANDROIDX_TEST_CORE)
     androidTestImplementation(ANDROIDX_TEST_RUNNER)
diff --git a/loader/loader/src/androidTest/java/androidx/loader/app/LoaderInfoTest.java b/loader/loader/src/androidTest/java/androidx/loader/app/LoaderInfoTest.java
index d1afd22..74897b2 100644
--- a/loader/loader/src/androidTest/java/androidx/loader/app/LoaderInfoTest.java
+++ b/loader/loader/src/androidTest/java/androidx/loader/app/LoaderInfoTest.java
@@ -19,13 +19,11 @@
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
 
 import android.content.Context;
 
 import androidx.lifecycle.Lifecycle;
-import androidx.lifecycle.LifecycleOwner;
-import androidx.lifecycle.LifecycleRegistry;
+import androidx.lifecycle.testing.TestLifecycleOwner;
 import androidx.loader.app.test.DelayLoader;
 import androidx.loader.app.test.DummyLoaderCallbacks;
 import androidx.loader.content.Loader;
@@ -45,16 +43,11 @@
 @LargeTest
 public class LoaderInfoTest {
 
-    private LifecycleOwner mOwner;
-    private LifecycleRegistry mRegistry;
+    private TestLifecycleOwner mOwner;
 
     @Before
     public void setup() {
-        mOwner = mock(LifecycleOwner.class);
-        mRegistry = new LifecycleRegistry(mOwner);
-        when(mOwner.getLifecycle()).thenReturn(mRegistry);
-        mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE);
-        mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START);
+        mOwner = new TestLifecycleOwner();
     }
 
     @Test
@@ -145,13 +138,13 @@
         assertTrue("onLoadFinished should be called after setCallback",
                 loaderCallback.mOnLoadFinished);
 
-        mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_STOP);
+        mOwner.handleLifecycleEvent(Lifecycle.Event.ON_STOP);
         loaderCallback.mOnLoadFinished = false;
         loaderInfo.markForRedelivery();
         assertFalse("onLoadFinished should not be called when stopped after markForRedelivery",
                 loaderCallback.mOnLoadFinished);
 
-        mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START);
+        mOwner.handleLifecycleEvent(Lifecycle.Event.ON_START);
         assertTrue("onLoadFinished should be called after markForRedelivery",
                 loaderCallback.mOnLoadFinished);
     }
@@ -168,7 +161,7 @@
         assertTrue("onLoadFinished for initial should be called after setCallback initial",
                 initialCallback.mOnLoadFinished);
 
-        mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_STOP);
+        mOwner.handleLifecycleEvent(Lifecycle.Event.ON_STOP);
         initialCallback.mOnLoadFinished = false;
         loaderInfo.markForRedelivery();
         assertFalse("onLoadFinished should not be called when stopped after markForRedelivery",
@@ -179,7 +172,7 @@
                 new DummyLoaderCallbacks(mock(Context.class));
         loaderInfo.setCallback(mOwner, replacementCallback);
 
-        mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START);
+        mOwner.handleLifecycleEvent(Lifecycle.Event.ON_START);
         assertFalse("onLoadFinished for initial should not be called "
                         + "after setCallback replacement",
                 initialCallback.mOnLoadFinished);
diff --git a/loader/loader/src/androidTest/java/androidx/loader/app/LoaderManagerTest.java b/loader/loader/src/androidTest/java/androidx/loader/app/LoaderManagerTest.java
index 8e7d67f..09228b9 100644
--- a/loader/loader/src/androidTest/java/androidx/loader/app/LoaderManagerTest.java
+++ b/loader/loader/src/androidTest/java/androidx/loader/app/LoaderManagerTest.java
@@ -25,11 +25,8 @@
 import android.os.Bundle;
 
 import androidx.annotation.NonNull;
-import androidx.lifecycle.Lifecycle;
-import androidx.lifecycle.LifecycleOwner;
-import androidx.lifecycle.LifecycleRegistry;
 import androidx.lifecycle.ViewModelStore;
-import androidx.lifecycle.ViewModelStoreOwner;
+import androidx.lifecycle.testing.TestLifecycleOwner;
 import androidx.loader.app.test.DelayLoaderCallbacks;
 import androidx.loader.app.test.DummyLoaderCallbacks;
 import androidx.loader.content.Loader;
@@ -53,7 +50,7 @@
 
     @Before
     public void setup() {
-        mLoaderManager = LoaderManager.getInstance(new LoaderOwner());
+        mLoaderManager = LoaderManager.getInstance(new TestLifecycleOwner(), new ViewModelStore());
     }
 
     @Test
@@ -310,26 +307,4 @@
     public void enforceOnMainThread_destroyLoader() {
         mLoaderManager.destroyLoader(-1);
     }
-
-    class LoaderOwner implements LifecycleOwner, ViewModelStoreOwner {
-
-        private LifecycleRegistry mLifecycle = new LifecycleRegistry(this);
-        private ViewModelStore mViewModelStore = new ViewModelStore();
-
-        LoaderOwner() {
-            mLifecycle.handleLifecycleEvent(Lifecycle.Event.ON_START);
-        }
-
-        @NonNull
-        @Override
-        public Lifecycle getLifecycle() {
-            return mLifecycle;
-        }
-
-        @NonNull
-        @Override
-        public ViewModelStore getViewModelStore() {
-            return mViewModelStore;
-        }
-    }
 }
diff --git a/loader/loader/src/main/java/androidx/loader/app/LoaderManager.java b/loader/loader/src/main/java/androidx/loader/app/LoaderManager.java
index 0dd0955..cf46746 100644
--- a/loader/loader/src/main/java/androidx/loader/app/LoaderManager.java
+++ b/loader/loader/src/main/java/androidx/loader/app/LoaderManager.java
@@ -24,6 +24,7 @@
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.lifecycle.LifecycleOwner;
+import androidx.lifecycle.ViewModelStore;
 import androidx.lifecycle.ViewModelStoreOwner;
 import androidx.loader.content.Loader;
 
@@ -130,6 +131,12 @@
         return new LoaderManagerImpl(owner, owner.getViewModelStore());
     }
 
+    @NonNull
+    static LoaderManager getInstance(@NonNull LifecycleOwner owner,
+            @NonNull ViewModelStore viewModelStore) {
+        return new LoaderManagerImpl(owner, viewModelStore);
+    }
+
     /**
      * Ensures a loader is initialized and active.  If the loader doesn't
      * already exist, one is created and (if the activity/fragment is currently
diff --git a/navigation/navigation-runtime/build.gradle b/navigation/navigation-runtime/build.gradle
index 5b1201a..2c8832b 100644
--- a/navigation/navigation-runtime/build.gradle
+++ b/navigation/navigation-runtime/build.gradle
@@ -34,6 +34,7 @@
     api("androidx.savedstate:savedstate:1.0.0")
     api("androidx.lifecycle:lifecycle-viewmodel-savedstate:2.2.0")
 
+    androidTestImplementation(project(":lifecycle:lifecycle-runtime-testing"))
     androidTestImplementation(project(":internal-testutils-navigation"))
     androidTestImplementation(ANDROIDX_TEST_EXT_JUNIT)
     androidTestImplementation(ANDROIDX_TEST_CORE)
diff --git a/navigation/navigation-runtime/src/androidTest/java/androidx/navigation/NavBackStackEntryLifecycleTest.kt b/navigation/navigation-runtime/src/androidTest/java/androidx/navigation/NavBackStackEntryLifecycleTest.kt
index 0e477be..ba2eb51 100644
--- a/navigation/navigation-runtime/src/androidTest/java/androidx/navigation/NavBackStackEntryLifecycleTest.kt
+++ b/navigation/navigation-runtime/src/androidTest/java/androidx/navigation/NavBackStackEntryLifecycleTest.kt
@@ -20,7 +20,7 @@
 import androidx.lifecycle.Lifecycle
 import androidx.lifecycle.LifecycleEventObserver
 import androidx.lifecycle.LifecycleOwner
-import androidx.lifecycle.LifecycleRegistry
+import androidx.lifecycle.testing.TestLifecycleOwner
 import androidx.navigation.test.FloatingTestNavigator
 import androidx.navigation.test.R
 import androidx.navigation.test.dialog
@@ -581,12 +581,7 @@
     }
 
     private fun createNavController(
-        lifecycleOwner: LifecycleOwner = object : LifecycleOwner {
-            private val lifecycleRegistry = LifecycleRegistry(this).apply {
-                currentState = Lifecycle.State.RESUMED
-            }
-            override fun getLifecycle() = lifecycleRegistry
-        }
+        lifecycleOwner: LifecycleOwner = TestLifecycleOwner(Lifecycle.State.RESUMED)
     ): NavController {
         val navController = NavHostController(ApplicationProvider.getApplicationContext())
         navController.navigatorProvider.addNavigator(TestNavigator())
diff --git a/paging/runtime/build.gradle b/paging/runtime/build.gradle
index 4cc51af..6e3fe698 100644
--- a/paging/runtime/build.gradle
+++ b/paging/runtime/build.gradle
@@ -44,6 +44,7 @@
     androidTestImplementation project(':paging:paging-testutils')
     androidTestImplementation project(':internal-testutils-common')
     androidTestImplementation project(':internal-testutils-ktx')
+    androidTestImplementation(project(":lifecycle:lifecycle-runtime-testing"))
     androidTestImplementation(ANDROIDX_TEST_CORE)
     androidTestImplementation(ANDROIDX_TEST_EXT_JUNIT)
     androidTestImplementation(ANDROIDX_TEST_RUNNER)
diff --git a/paging/runtime/src/androidTest/java/androidx/paging/LivePagedListBuilderTest.kt b/paging/runtime/src/androidTest/java/androidx/paging/LivePagedListBuilderTest.kt
index 9132af3..f61b6e3 100644
--- a/paging/runtime/src/androidTest/java/androidx/paging/LivePagedListBuilderTest.kt
+++ b/paging/runtime/src/androidTest/java/androidx/paging/LivePagedListBuilderTest.kt
@@ -19,9 +19,8 @@
 import androidx.arch.core.executor.ArchTaskExecutor
 import androidx.arch.core.executor.TaskExecutor
 import androidx.lifecycle.Lifecycle
-import androidx.lifecycle.LifecycleOwner
-import androidx.lifecycle.LifecycleRegistry
 import androidx.lifecycle.Observer
+import androidx.lifecycle.testing.TestLifecycleOwner
 import androidx.paging.LoadState.Error
 import androidx.paging.LoadState.Idle
 import androidx.paging.LoadState.Loading
@@ -46,29 +45,19 @@
 import org.junit.runner.RunWith
 import org.junit.runners.JUnit4
 
+@ExperimentalCoroutinesApi
 @SmallTest
 @RunWith(JUnit4::class)
 class LivePagedListBuilderTest {
     private val mainDispatcher = TestDispatcher()
     private val backgroundExecutor = TestExecutor()
-    private val lifecycleOwner = object : LifecycleOwner {
-        private val lifecycle = LifecycleRegistry(this)
-
-        override fun getLifecycle(): Lifecycle {
-            return lifecycle
-        }
-
-        fun handleEvent(event: Lifecycle.Event) {
-            lifecycle.handleLifecycleEvent(event)
-        }
-    }
+    private val lifecycleOwner = TestLifecycleOwner()
 
     private data class LoadStateEvent(
         val type: LoadType,
         val state: LoadState
     )
 
-    @ExperimentalCoroutinesApi
     @Before
     fun setup() {
         Dispatchers.setMain(mainDispatcher)
@@ -85,13 +74,13 @@
                 return true
             }
         })
-        lifecycleOwner.handleEvent(Lifecycle.Event.ON_START)
+        lifecycleOwner.handleLifecycleEvent(Lifecycle.Event.ON_START)
     }
 
     @ExperimentalCoroutinesApi
     @After
     fun teardown() {
-        lifecycleOwner.handleEvent(Lifecycle.Event.ON_STOP)
+        lifecycleOwner.handleLifecycleEvent(Lifecycle.Event.ON_STOP)
         ArchTaskExecutor.getInstance().setDelegate(null)
         Dispatchers.resetMain()
     }
diff --git a/room/integration-tests/testapp/build.gradle b/room/integration-tests/testapp/build.gradle
index 5f24684..652a8f8 100644
--- a/room/integration-tests/testapp/build.gradle
+++ b/room/integration-tests/testapp/build.gradle
@@ -30,6 +30,8 @@
 
 android {
     defaultConfig {
+        multiDexEnabled true
+
         javaCompileOptions {
             annotationProcessorOptions {
                 arguments = [
@@ -52,6 +54,7 @@
     implementation(project(":sqlite:sqlite-framework"))
     implementation(project(":arch:core-runtime"))
     implementation(project(":lifecycle:lifecycle-livedata"))
+    implementation(MULTIDEX)
 
     // FINDBUGS dependency resolves an app/testapp version conflict.
     implementation(FINDBUGS)
@@ -65,6 +68,8 @@
     androidTestImplementation(project(":room:room-guava"))
     androidTestImplementation("androidx.arch.core:core-testing:2.0.1")
     androidTestImplementation("androidx.paging:paging-runtime:2.0.0")
+    androidTestImplementation(project(":lifecycle:lifecycle-runtime"))
+    androidTestImplementation(project(":lifecycle:lifecycle-runtime-testing"))
 
     // FINDBUGS dependency resolves an app/testapp version conflict.
     androidTestImplementation(FINDBUGS)
diff --git a/room/integration-tests/testapp/src/androidTest/java/androidx/room/integration/testapp/paging/DataSourceFactoryTest.java b/room/integration-tests/testapp/src/androidTest/java/androidx/room/integration/testapp/paging/DataSourceFactoryTest.java
index d95338c..8598f25 100644
--- a/room/integration-tests/testapp/src/androidTest/java/androidx/room/integration/testapp/paging/DataSourceFactoryTest.java
+++ b/room/integration-tests/testapp/src/androidTest/java/androidx/room/integration/testapp/paging/DataSourceFactoryTest.java
@@ -29,11 +29,11 @@
 import androidx.lifecycle.LifecycleOwner;
 import androidx.lifecycle.LiveData;
 import androidx.lifecycle.Observer;
+import androidx.lifecycle.testing.TestLifecycleOwner;
 import androidx.paging.DataSource;
 import androidx.paging.LivePagedListBuilder;
 import androidx.paging.PagedList;
 import androidx.room.integration.testapp.test.TestDatabaseTest;
-import androidx.room.integration.testapp.test.TestLifecycleOwner;
 import androidx.room.integration.testapp.test.TestUtil;
 import androidx.room.integration.testapp.vo.Pet;
 import androidx.room.integration.testapp.vo.User;
@@ -109,8 +109,7 @@
 
         final LiveData<PagedList<User>> livePagedUsers = factory.create();
 
-        final TestLifecycleOwner testOwner = new TestLifecycleOwner();
-        testOwner.handleEvent(Lifecycle.Event.ON_CREATE);
+        final TestLifecycleOwner testOwner = new TestLifecycleOwner(Lifecycle.State.CREATED);
         drain();
         PagedListObserver<User> observer = new PagedListObserver<>();
 
@@ -118,7 +117,7 @@
         assertThat(observer.get(), nullValue());
         observer.reset();
 
-        testOwner.handleEvent(Lifecycle.Event.ON_START);
+        testOwner.handleLifecycleEvent(Lifecycle.Event.ON_START);
         drain();
 
         final PagedList<User> pagedList1 = observer.get();
@@ -158,10 +157,10 @@
         mExecutorRule.drainTasks(60, TimeUnit.SECONDS);
     }
 
+    @SuppressWarnings("unchecked")
     private void observe(final LiveData liveData, final LifecycleOwner provider,
             final Observer observer) throws ExecutionException, InterruptedException {
         FutureTask<Void> futureTask = new FutureTask<>(() -> {
-            //noinspection unchecked
             liveData.observe(provider, observer);
             return null;
         });
@@ -180,7 +179,6 @@
 
         PagedListObserver<UserAndAllPets> observer = new PagedListObserver<>();
         final TestLifecycleOwner lifecycleOwner = new TestLifecycleOwner();
-        lifecycleOwner.handleEvent(Lifecycle.Event.ON_START);
         observe(liveData, lifecycleOwner, observer);
         drain();
         assertThat(observer.get(), is(Collections.emptyList()));
diff --git a/room/integration-tests/testapp/src/androidTest/java/androidx/room/integration/testapp/test/InvalidationTrackerTest.java b/room/integration-tests/testapp/src/androidTest/java/androidx/room/integration/testapp/test/InvalidationTrackerTest.java
index 0916102..0659ea2 100644
--- a/room/integration-tests/testapp/src/androidTest/java/androidx/room/integration/testapp/test/InvalidationTrackerTest.java
+++ b/room/integration-tests/testapp/src/androidTest/java/androidx/room/integration/testapp/test/InvalidationTrackerTest.java
@@ -32,6 +32,7 @@
 import androidx.arch.core.executor.testing.CountingTaskExecutorRule;
 import androidx.lifecycle.Lifecycle;
 import androidx.lifecycle.LiveData;
+import androidx.lifecycle.testing.TestLifecycleOwner;
 import androidx.room.Dao;
 import androidx.room.Database;
 import androidx.room.Entity;
@@ -147,11 +148,12 @@
 
         mDb.getItemDao().insert(new Item(1, "v1"));
 
-        final TestLifecycleOwner lifecycleOwner = new TestLifecycleOwner();
+        final TestLifecycleOwner lifecycleOwner = new TestLifecycleOwner(
+                Lifecycle.State.INITIALIZED);
         TestObserver<Item> observer = new MyObserver<>();
         TestUtil.observeOnMainThread(liveData, lifecycleOwner, observer);
         assertThat(observer.hasValue(), is(false));
-        lifecycleOwner.handleEvent(Lifecycle.Event.ON_START);
+        lifecycleOwner.handleLifecycleEvent(Lifecycle.Event.ON_START);
         drain();
         assertThat(observer.get(), is(new Item(1, "v1")));
 
diff --git a/room/integration-tests/testapp/src/androidTest/java/androidx/room/integration/testapp/test/LiveDataQueryTest.java b/room/integration-tests/testapp/src/androidTest/java/androidx/room/integration/testapp/test/LiveDataQueryTest.java
index 2978b70..d168766 100644
--- a/room/integration-tests/testapp/src/androidTest/java/androidx/room/integration/testapp/test/LiveDataQueryTest.java
+++ b/room/integration-tests/testapp/src/androidTest/java/androidx/room/integration/testapp/test/LiveDataQueryTest.java
@@ -29,6 +29,7 @@
 import androidx.lifecycle.Lifecycle;
 import androidx.lifecycle.LiveData;
 import androidx.lifecycle.Observer;
+import androidx.lifecycle.testing.TestLifecycleOwner;
 import androidx.room.InvalidationTrackerTrojan;
 import androidx.room.Room;
 import androidx.room.integration.testapp.FtsTestDatabase;
@@ -82,14 +83,13 @@
     @Test
     public void observeById() throws InterruptedException, ExecutionException, TimeoutException {
         final LiveData<User> userLiveData = mUserDao.liveUserById(5);
-        final TestLifecycleOwner testOwner = new TestLifecycleOwner();
-        testOwner.handleEvent(Lifecycle.Event.ON_CREATE);
+        final TestLifecycleOwner testOwner = new TestLifecycleOwner(Lifecycle.State.CREATED);
         final TestObserver<User> observer = new MyTestObserver<>();
         TestUtil.observeOnMainThread(userLiveData, testOwner, observer);
         assertThat(observer.hasValue(), is(false));
         observer.reset();
 
-        testOwner.handleEvent(Lifecycle.Event.ON_START);
+        testOwner.handleLifecycleEvent(Lifecycle.Event.ON_START);
         assertThat(observer.get(), is(nullValue()));
 
         // another id
@@ -109,7 +109,7 @@
         assertThat(updated, is(notNullValue()));
         assertThat(updated.getName(), is("foo-foo-foo"));
 
-        testOwner.handleEvent(Lifecycle.Event.ON_STOP);
+        testOwner.handleLifecycleEvent(Lifecycle.Event.ON_STOP);
         observer.reset();
         u5.setName("baba");
         mUserDao.insertOrReplace(u5);
@@ -121,7 +121,6 @@
             TimeoutException {
         final LiveData<List<User>> userLiveData = mUserDao.liveUsersListByName("frida");
         final TestLifecycleOwner lifecycleOwner = new TestLifecycleOwner();
-        lifecycleOwner.handleEvent(Lifecycle.Event.ON_START);
         final TestObserver<List<User>> observer = new MyTestObserver<>();
         TestUtil.observeOnMainThread(userLiveData, lifecycleOwner, observer);
         assertThat(observer.get(), is(Collections.<User>emptyList()));
@@ -143,7 +142,7 @@
         mUserDao.insertOrReplace(user1);
         assertThat(observer.get(), is(Collections.<User>emptyList()));
 
-        lifecycleOwner.handleEvent(Lifecycle.Event.ON_STOP);
+        lifecycleOwner.handleLifecycleEvent(Lifecycle.Event.ON_STOP);
 
         observer.reset();
         final User user3 = TestUtil.createUser(9);
@@ -157,7 +156,7 @@
         mUserDao.insertOrReplace(user4);
         assertThat(observer.hasValue(), is(false));
 
-        lifecycleOwner.handleEvent(Lifecycle.Event.ON_START);
+        lifecycleOwner.handleLifecycleEvent(Lifecycle.Event.ON_START);
         assertThat(observer.get(), is(Arrays.asList(user4, user3)));
     }
 
@@ -178,7 +177,6 @@
         users[3].setWeight(21);
 
         final TestLifecycleOwner lifecycleOwner = new TestLifecycleOwner();
-        lifecycleOwner.handleEvent(Lifecycle.Event.ON_START);
 
         final TestObserver<AvgWeightByAge> observer = new MyTestObserver<>();
         LiveData<AvgWeightByAge> liveData = mUserDao.maxWeightByAgeGroup();
@@ -206,7 +204,6 @@
         pet.setUserId(user.getId());
 
         final TestLifecycleOwner lifecycleOwner = new TestLifecycleOwner();
-        lifecycleOwner.handleEvent(Lifecycle.Event.ON_START);
 
         final TestObserver<PetWithUser> observer = new MyTestObserver<>();
         LiveData<PetWithUser> liveData = mPetDao.petWithUserLiveData(3);
@@ -227,7 +224,6 @@
         final LiveData<UserAndAllPets> liveData = mUserPetDao.liveUserWithPets(3);
         final TestObserver<UserAndAllPets> observer = new MyTestObserver<>();
         final TestLifecycleOwner lifecycleOwner = new TestLifecycleOwner();
-        lifecycleOwner.handleEvent(Lifecycle.Event.ON_START);
         TestUtil.observeOnMainThread(liveData, lifecycleOwner, observer);
         assertThat(observer.get(), is(nullValue()));
 
@@ -260,7 +256,6 @@
         toy.setName("ball");
 
         final TestLifecycleOwner lifecycleOwner = new TestLifecycleOwner();
-        lifecycleOwner.handleEvent(Lifecycle.Event.ON_START);
         final TestObserver<PetsToys> observer = new MyTestObserver<>();
         TestUtil.observeOnMainThread(liveData, lifecycleOwner, observer);
         assertThat(observer.get(), is(expected));
@@ -305,7 +300,6 @@
         LiveData<PlaylistWithSongs> liveData = musicDao.getPlaylistsWithSongsLiveData(1);
 
         final TestLifecycleOwner lifecycleOwner = new TestLifecycleOwner();
-        lifecycleOwner.handleEvent(Lifecycle.Event.ON_START);
         final TestObserver<PlaylistWithSongs> observer = new MyTestObserver<>();
         TestUtil.observeOnMainThread(liveData, lifecycleOwner, observer);
 
@@ -330,7 +324,6 @@
         List<String> expected = new ArrayList<>();
 
         final TestLifecycleOwner lifecycleOwner = new TestLifecycleOwner();
-        lifecycleOwner.handleEvent(Lifecycle.Event.ON_START);
         final TestObserver<List<String>> observer = new MyTestObserver<>();
         TestUtil.observeOnMainThread(actual, lifecycleOwner, observer);
         assertThat(observer.get(), is(expected));
@@ -371,7 +364,6 @@
                 .build();
         final MailDao mailDao = db.getMailDao();
         final TestLifecycleOwner lifecycleOwner = new TestLifecycleOwner();
-        lifecycleOwner.handleEvent(Lifecycle.Event.ON_START);
 
         final TestObserver<List<Mail>> observer = new MyTestObserver<>();
         LiveData<List<Mail>> liveData = mailDao.getLiveDataMail();
@@ -395,7 +387,6 @@
                 .build();
         final SongDao songDao = db.getSongDao();
         final TestLifecycleOwner lifecycleOwner = new TestLifecycleOwner();
-        lifecycleOwner.handleEvent(Lifecycle.Event.ON_START);
 
         final TestObserver<List<Song>> songObserver = new MyTestObserver<>();
         final TestObserver<List<SongDescription>> songDescriptionObserver = new MyTestObserver<>();
@@ -451,8 +442,7 @@
     public void handleGc() throws ExecutionException, InterruptedException, TimeoutException {
         LiveData<User> liveData = mUserDao.liveUserById(3);
         final TestObserver<User> observer = new MyTestObserver<>();
-        final TestLifecycleOwner lifecycleOwner = new TestLifecycleOwner();
-        lifecycleOwner.handleEvent(Lifecycle.Event.ON_START);
+        final TestLifecycleOwner lifecycleOwner = new TestLifecycleOwner(Lifecycle.State.STARTED);
         TestUtil.observeOnMainThread(liveData, lifecycleOwner, observer);
         assertThat(observer.get(), is(nullValue()));
         observer.reset();
@@ -466,12 +456,7 @@
         assertThat(observer.get().getName(), is(name));
 
         // release references
-        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
-            @Override
-            public void run() {
-                lifecycleOwner.handleEvent(Lifecycle.Event.ON_DESTROY);
-            }
-        });
+        lifecycleOwner.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY);
         WeakReference<LiveData> weakLiveData = new WeakReference<LiveData>(liveData);
         //noinspection UnusedAssignment
         liveData = null;
@@ -525,7 +510,6 @@
         user.setAdmin(false);
         LiveData<Boolean> adminLiveData = mUserDao.isAdminLiveData(3);
         final TestLifecycleOwner lifecycleOwner = new TestLifecycleOwner();
-        lifecycleOwner.handleEvent(Lifecycle.Event.ON_START);
         final TestObserver<Boolean> observer = new MyTestObserver<>();
         TestUtil.observeOnMainThread(adminLiveData, lifecycleOwner, observer);
         assertThat(observer.get(), is(nullValue()));
diff --git a/room/integration-tests/testapp/src/androidTest/java/androidx/room/integration/testapp/test/QueryTransactionTest.java b/room/integration-tests/testapp/src/androidTest/java/androidx/room/integration/testapp/test/QueryTransactionTest.java
index 79539f2..24caf3e 100644
--- a/room/integration-tests/testapp/src/androidTest/java/androidx/room/integration/testapp/test/QueryTransactionTest.java
+++ b/room/integration-tests/testapp/src/androidTest/java/androidx/room/integration/testapp/test/QueryTransactionTest.java
@@ -25,6 +25,7 @@
 import androidx.arch.core.executor.testing.CountingTaskExecutorRule;
 import androidx.lifecycle.Lifecycle;
 import androidx.lifecycle.LiveData;
+import androidx.lifecycle.testing.TestLifecycleOwner;
 import androidx.paging.DataSource;
 import androidx.paging.LivePagedListBuilder;
 import androidx.paging.PagedList;
@@ -44,7 +45,6 @@
 import androidx.room.paging.LimitOffsetDataSource;
 import androidx.test.core.app.ApplicationProvider;
 import androidx.test.filters.SmallTest;
-import androidx.test.platform.app.InstrumentationRegistry;
 
 import org.junit.After;
 import org.junit.Before;
@@ -92,9 +92,6 @@
 
     @Before
     public void initDb() {
-        InstrumentationRegistry.getInstrumentation().runOnMainSync(
-                () -> mLifecycleOwner.handleEvent(Lifecycle.Event.ON_START));
-
         resetTransactionCount();
         mDb = Room.inMemoryDatabaseBuilder(ApplicationProvider.getApplicationContext(),
                 TransactionDb.class).build();
@@ -104,8 +101,7 @@
 
     @After
     public void closeDb() {
-        InstrumentationRegistry.getInstrumentation().runOnMainSync(
-                () -> mLifecycleOwner.handleEvent(Lifecycle.Event.ON_DESTROY));
+        mLifecycleOwner.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY);
         drain();
         mDb.close();
     }
diff --git a/room/integration-tests/testapp/src/androidTest/java/androidx/room/integration/testapp/test/TestLifecycleOwner.java b/room/integration-tests/testapp/src/androidTest/java/androidx/room/integration/testapp/test/TestLifecycleOwner.java
deleted file mode 100644
index fa1fc3b..0000000
--- a/room/integration-tests/testapp/src/androidTest/java/androidx/room/integration/testapp/test/TestLifecycleOwner.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.room.integration.testapp.test;
-
-import androidx.lifecycle.Lifecycle;
-import androidx.lifecycle.LifecycleOwner;
-import androidx.lifecycle.LifecycleRegistry;
-
-public class TestLifecycleOwner implements LifecycleOwner {
-
-    private LifecycleRegistry mLifecycle;
-
-    public TestLifecycleOwner() {
-        mLifecycle = new LifecycleRegistry(this);
-    }
-
-    @Override
-    public Lifecycle getLifecycle() {
-        return mLifecycle;
-    }
-
-    public void handleEvent(Lifecycle.Event event) {
-        mLifecycle.handleLifecycleEvent(event);
-    }
-}
diff --git a/room/integration-tests/testapp/src/main/AndroidManifest.xml b/room/integration-tests/testapp/src/main/AndroidManifest.xml
index 6f6f804..45c55ab 100644
--- a/room/integration-tests/testapp/src/main/AndroidManifest.xml
+++ b/room/integration-tests/testapp/src/main/AndroidManifest.xml
@@ -17,6 +17,7 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
           package="androidx.room.integration.testapp">
     <application
+        android:name="androidx.multidex.MultiDexApplication"
         android:allowBackup="true"
         android:supportsRtl="true">
         <service
diff --git a/work/workmanager/build.gradle b/work/workmanager/build.gradle
index b9eb7cd..273ab18 100644
--- a/work/workmanager/build.gradle
+++ b/work/workmanager/build.gradle
@@ -75,6 +75,7 @@
     androidTestImplementation(ANDROIDX_TEST_EXT_JUNIT)
     androidTestImplementation(ANDROIDX_TEST_CORE)
     androidTestImplementation("androidx.arch.core:core-testing:2.1.0")
+    androidTestImplementation(project(":lifecycle:lifecycle-runtime-testing"))
     androidTestImplementation(ANDROIDX_TEST_RUNNER)
     androidTestImplementation(ESPRESSO_CORE)
     androidTestImplementation(MOCKITO_CORE, libs.exclude_bytebuddy) // DexMaker has its own MockMaker
diff --git a/work/workmanager/src/androidTest/java/androidx/work/TestLifecycleOwner.java b/work/workmanager/src/androidTest/java/androidx/work/TestLifecycleOwner.java
deleted file mode 100644
index 336a52d..0000000
--- a/work/workmanager/src/androidTest/java/androidx/work/TestLifecycleOwner.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.work;
-
-import androidx.lifecycle.Lifecycle;
-import androidx.lifecycle.LifecycleOwner;
-import androidx.lifecycle.LifecycleRegistry;
-
-/**
- * Test Lifecycle Owner that begins in ON_START state.
- */
-
-public class TestLifecycleOwner implements LifecycleOwner {
-    public LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);
-
-    public TestLifecycleOwner() {
-        mLifecycleRegistry.markState(Lifecycle.State.STARTED);
-    }
-
-    @Override
-    public Lifecycle getLifecycle() {
-        return mLifecycleRegistry;
-    }
-}
diff --git a/work/workmanager/src/androidTest/java/androidx/work/impl/WorkContinuationImplTest.java b/work/workmanager/src/androidTest/java/androidx/work/impl/WorkContinuationImplTest.java
index 4228970..9c1f26d 100644
--- a/work/workmanager/src/androidTest/java/androidx/work/impl/WorkContinuationImplTest.java
+++ b/work/workmanager/src/androidTest/java/androidx/work/impl/WorkContinuationImplTest.java
@@ -35,7 +35,6 @@
 import androidx.annotation.NonNull;
 import androidx.arch.core.executor.ArchTaskExecutor;
 import androidx.arch.core.executor.TaskExecutor;
-import androidx.lifecycle.Lifecycle;
 import androidx.test.core.app.ApplicationProvider;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.LargeTest;
@@ -44,7 +43,6 @@
 import androidx.work.Configuration;
 import androidx.work.Data;
 import androidx.work.OneTimeWorkRequest;
-import androidx.work.TestLifecycleOwner;
 import androidx.work.WorkContinuation;
 import androidx.work.WorkInfo;
 import androidx.work.WorkManagerTest;
@@ -99,9 +97,6 @@
             }
         });
 
-        TestLifecycleOwner lifecycleOwner = new TestLifecycleOwner();
-        lifecycleOwner.mLifecycleRegistry.markState(Lifecycle.State.CREATED);
-
         mScheduler = mock(Scheduler.class);
         Context context = ApplicationProvider.getApplicationContext();
         mConfiguration = new Configuration.Builder()
diff --git a/work/workmanager/src/androidTest/java/androidx/work/impl/WorkManagerImplLargeExecutorTest.java b/work/workmanager/src/androidTest/java/androidx/work/impl/WorkManagerImplLargeExecutorTest.java
index 473a5c8..2bd0bc2 100644
--- a/work/workmanager/src/androidTest/java/androidx/work/impl/WorkManagerImplLargeExecutorTest.java
+++ b/work/workmanager/src/androidTest/java/androidx/work/impl/WorkManagerImplLargeExecutorTest.java
@@ -31,13 +31,13 @@
 import androidx.annotation.Nullable;
 import androidx.arch.core.executor.ArchTaskExecutor;
 import androidx.lifecycle.Observer;
+import androidx.lifecycle.testing.TestLifecycleOwner;
 import androidx.test.core.app.ApplicationProvider;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.LargeTest;
 import androidx.test.filters.SdkSuppress;
 import androidx.work.Configuration;
 import androidx.work.OneTimeWorkRequest;
-import androidx.work.TestLifecycleOwner;
 import androidx.work.WorkContinuation;
 import androidx.work.WorkInfo;
 import androidx.work.impl.background.greedy.GreedyScheduler;
diff --git a/work/workmanager/src/androidTest/java/androidx/work/impl/WorkManagerImplTest.java b/work/workmanager/src/androidTest/java/androidx/work/impl/WorkManagerImplTest.java
index 5e50d68..958c239 100644
--- a/work/workmanager/src/androidTest/java/androidx/work/impl/WorkManagerImplTest.java
+++ b/work/workmanager/src/androidTest/java/androidx/work/impl/WorkManagerImplTest.java
@@ -68,6 +68,7 @@
 import androidx.arch.core.executor.TaskExecutor;
 import androidx.lifecycle.LiveData;
 import androidx.lifecycle.Observer;
+import androidx.lifecycle.testing.TestLifecycleOwner;
 import androidx.sqlite.db.SupportSQLiteDatabase;
 import androidx.sqlite.db.SupportSQLiteOpenHelper;
 import androidx.test.core.app.ApplicationProvider;
@@ -85,7 +86,6 @@
 import androidx.work.ExistingPeriodicWorkPolicy;
 import androidx.work.OneTimeWorkRequest;
 import androidx.work.PeriodicWorkRequest;
-import androidx.work.TestLifecycleOwner;
 import androidx.work.WorkContinuation;
 import androidx.work.WorkInfo;
 import androidx.work.WorkRequest;
diff --git a/work/workmanager/src/androidTest/java/androidx/work/impl/utils/LiveDataUtilsTest.java b/work/workmanager/src/androidTest/java/androidx/work/impl/utils/LiveDataUtilsTest.java
index 49deb61..bd21bae 100644
--- a/work/workmanager/src/androidTest/java/androidx/work/impl/utils/LiveDataUtilsTest.java
+++ b/work/workmanager/src/androidTest/java/androidx/work/impl/utils/LiveDataUtilsTest.java
@@ -26,9 +26,9 @@
 import androidx.lifecycle.LiveData;
 import androidx.lifecycle.MutableLiveData;
 import androidx.lifecycle.Observer;
+import androidx.lifecycle.testing.TestLifecycleOwner;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
-import androidx.work.TestLifecycleOwner;
 import androidx.work.impl.utils.taskexecutor.InstantWorkTaskExecutor;
 import androidx.work.impl.utils.taskexecutor.TaskExecutor;