diff --git a/DynamicFeatureNavigation/XML/app/build.gradle.kts b/DynamicFeatureNavigation/XML/app/build.gradle.kts index 931ecc65..6fe21abd 100644 --- a/DynamicFeatureNavigation/XML/app/build.gradle.kts +++ b/DynamicFeatureNavigation/XML/app/build.gradle.kts @@ -40,11 +40,21 @@ android { } } + useLibrary("android.test.runner") + useLibrary("android.test.base") + useLibrary("android.test.mock") + + testOptions.unitTests.isIncludeAndroidResources = true + compileOptions { sourceCompatibility = JavaVersion.VERSION_1_8 targetCompatibility = JavaVersion.VERSION_1_8 } + kotlinOptions { + jvmTarget = JavaVersion.VERSION_1_8.toString() + } + dynamicFeatures = mutableSetOf(":dynamicfeature", ":includedgraphfeature") packagingOptions { @@ -54,8 +64,20 @@ android { dependencies { api("androidx.navigation:navigation-dynamic-features-fragment:2.3.0") - api("androidx.appcompat:appcompat:1.1.0") + api("androidx.appcompat:appcompat:1.2.0") api("androidx.constraintlayout:constraintlayout:1.1.3") + + // Testing + debugImplementation("androidx.fragment:fragment-testing:1.2.5") + + // Testing - JVM + testImplementation("androidx.test.ext:junit:1.1.1") + testImplementation("androidx.test.ext:truth:1.2.0") + testImplementation("org.robolectric:robolectric:4.3.1") + testImplementation("androidx.test.espresso:espresso-core:3.2.0") + testImplementation("androidx.test.espresso:espresso-contrib:3.2.0") + testImplementation("androidx.test.espresso:espresso-intents:3.2.0") + testImplementation("androidx.navigation:navigation-testing:2.3.0") } val bundletoolJar = project.rootDir.resolve("third_party/bundletool/bundletool-all-0.13.0.jar") diff --git a/DynamicFeatureNavigation/XML/app/src/test/java/com/google/android/samples/dynamicnavigator/MainFragmentTest.kt b/DynamicFeatureNavigation/XML/app/src/test/java/com/google/android/samples/dynamicnavigator/MainFragmentTest.kt new file mode 100644 index 00000000..86583eac --- /dev/null +++ b/DynamicFeatureNavigation/XML/app/src/test/java/com/google/android/samples/dynamicnavigator/MainFragmentTest.kt @@ -0,0 +1,61 @@ +/* + * Copyright 2020 Google LLC. + * + * 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 com.google.android.samples.dynamicnavigator + +import androidx.fragment.app.testing.launchFragmentInContainer +import androidx.navigation.Navigation +import androidx.navigation.testing.TestNavHostController +import androidx.test.core.app.ApplicationProvider +import androidx.test.espresso.Espresso.onView +import androidx.test.espresso.action.ViewActions.click +import androidx.test.espresso.matcher.ViewMatchers.withId +import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.test.filters.MediumTest +import org.junit.Assert +import org.junit.Test +import org.junit.runner.RunWith +import org.robolectric.annotation.Config + +@Config(manifest = Config.NONE) +@RunWith(AndroidJUnit4::class) +@MediumTest +class MainFragmentTest { + + @Test + fun testNavigationToDefaultMonitor() { + // Given + val navController = TestNavHostController(ApplicationProvider.getApplicationContext()) + navController.setGraph(R.navigation.nav_graph) + navController.setCurrentDestination(R.id.mainFragment) + + launchFragmentInContainer { + MainFragment().also { fragment -> + fragment.viewLifecycleOwnerLiveData.observeForever { viewLifecycleOwner -> + if (viewLifecycleOwner != null) { + Navigation.setViewNavController(fragment.requireView(), navController) + } + } + } + } + + // When + onView(withId(R.id.default_monitor)).perform(click()) + + // Then + Assert.assertEquals(R.id.defaultMonitorFragment, navController.currentDestination?.id) + } +} diff --git a/DynamicFeatureNavigation/XML/app/src/test/resources/robolectric.properties b/DynamicFeatureNavigation/XML/app/src/test/resources/robolectric.properties new file mode 100644 index 00000000..932b01b9 --- /dev/null +++ b/DynamicFeatureNavigation/XML/app/src/test/resources/robolectric.properties @@ -0,0 +1 @@ +sdk=28 diff --git a/DynamicFeatureNavigation/XML/build.gradle.kts b/DynamicFeatureNavigation/XML/build.gradle.kts index ee0885b9..caea925c 100644 --- a/DynamicFeatureNavigation/XML/build.gradle.kts +++ b/DynamicFeatureNavigation/XML/build.gradle.kts @@ -23,7 +23,7 @@ buildscript { jcenter() } dependencies { - classpath("com.android.tools.build:gradle:4.1.0-alpha08") + classpath("com.android.tools.build:gradle:4.1.0-rc01") classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.61") // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files diff --git a/DynamicFeatureNavigation/XML/dynamicfeature/build.gradle.kts b/DynamicFeatureNavigation/XML/dynamicfeature/build.gradle.kts index 1b75ceb7..ee9cd73c 100644 --- a/DynamicFeatureNavigation/XML/dynamicfeature/build.gradle.kts +++ b/DynamicFeatureNavigation/XML/dynamicfeature/build.gradle.kts @@ -32,8 +32,24 @@ android { sourceCompatibility = JavaVersion.VERSION_1_8 targetCompatibility = JavaVersion.VERSION_1_8 } + + kotlinOptions { + jvmTarget = JavaVersion.VERSION_1_8.toString() + } } dependencies { implementation(project(":app")) + + // Testing + debugImplementation("androidx.fragment:fragment-testing:1.2.5") + + // Testing - JVM + testImplementation("androidx.test.ext:junit:1.1.1") + testImplementation("androidx.test.ext:truth:1.2.0") + testImplementation("org.robolectric:robolectric:4.3.1") + testImplementation("androidx.test.espresso:espresso-core:3.2.0") + testImplementation("androidx.test.espresso:espresso-contrib:3.2.0") + testImplementation("androidx.test.espresso:espresso-intents:3.2.0") + testImplementation("androidx.navigation:navigation-testing:2.3.0") } diff --git a/DynamicFeatureNavigation/XML/dynamicfeature/src/test/java/com/google/android/samples/dynamicnavigator/feature/FeatureFragmentTest.kt b/DynamicFeatureNavigation/XML/dynamicfeature/src/test/java/com/google/android/samples/dynamicnavigator/feature/FeatureFragmentTest.kt new file mode 100644 index 00000000..65e0805b --- /dev/null +++ b/DynamicFeatureNavigation/XML/dynamicfeature/src/test/java/com/google/android/samples/dynamicnavigator/feature/FeatureFragmentTest.kt @@ -0,0 +1,62 @@ +/* + * Copyright 2020 Google LLC. + * + * 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 com.google.android.samples.dynamicnavigator.feature + +import androidx.fragment.app.testing.launchFragmentInContainer +import androidx.navigation.Navigation +import androidx.navigation.testing.TestNavHostController +import androidx.test.core.app.ApplicationProvider +import androidx.test.espresso.Espresso.onView +import androidx.test.espresso.action.ViewActions.click +import androidx.test.espresso.matcher.ViewMatchers.withId +import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.test.filters.MediumTest +import org.junit.Assert +import org.junit.Test +import org.junit.runner.RunWith +import org.robolectric.annotation.Config +import com.google.android.samples.dynamicnavigator.R as baseR + +@Config(manifest = Config.NONE) +@RunWith(AndroidJUnit4::class) +@MediumTest +class FeatureFragmentTest { + + @Test + fun testNavigationToIncludedGraph() { + // Given + val navController = TestNavHostController(ApplicationProvider.getApplicationContext()) + navController.setGraph(R.navigation.feature_nav) + navController.setCurrentDestination(R.id.featureFragmentNested) + + launchFragmentInContainer { + FeatureFragment().also { fragment -> + fragment.viewLifecycleOwnerLiveData.observeForever { viewLifecycleOwner -> + if (viewLifecycleOwner != null) { + Navigation.setViewNavController(fragment.requireView(), navController) + } + } + } + } + + // When + onView(withId(R.id.navigateToIncludedGraphFeature)).perform(click()) + + // Then + Assert.assertEquals(baseR.id.includedGraph, navController.currentDestination?.id) + } +}