如何为Android Navigation Controller编写测试

Rez*_*adi 7 android android-testing android-jetpack android-architecture-navigation

我正在使用目前处于alpha状态的新导航控制器.它工作正常,但我找不到任何文档或示例应用程序,以了解如何进行测试.谷歌也发布了android.arch.navigation:navigation-testing用于测试导航的库,但同样没有文档.

任何帮助或建议将不胜感激.

Mar*_*ler 10

这是我最近的一个带有FragmentScenarioand 的例子TestNavHostController

dependencies {
    androidTestImplementation "androidx.navigation:navigation-testing:2.3.5"
    implementation "androidx.navigation:navigation-fragment:2.3.5"
    implementation "androidx.navigation:navigation-runtime:2.3.5"
}
Run Code Online (Sandbox Code Playgroud)

和仪器测试:

/**
 * Instrumented Navigation Test
 * @author Martin Zeitler
 */
@RunWith(AndroidJUnit4.class)
public class NavControllerTest {

    @IdRes
    private final int theme = R.style.Theme_AppCompat_DayNight;

    @Test
    public void testHomeFragmentToLoginFragment() {
        
        Bundle args = new Bundle();
        FragmentScenario<HomeFragment> navhostScenario = FragmentScenario.launchInContainer(HomeFragment.class, args, theme, Lifecycle.State.STARTED);

        navhostScenario.onFragment(fragment -> {

            // Create a NavController and set the NavController property on the fragment
            assertNotNull(fragment.getActivity());
            TestNavHostController navController = new TestNavHostController(fragment.getActivity());
            fragment.getActivity().runOnUiThread(() -> navController.setGraph(R.navigation.nav_graph));
            Navigation.setViewNavController(fragment.requireView(), navController);

            // Then navigate
            navController.navigate(R.id.action_homeFragment_to_loginFragment);
            NavDestination destination = navController.getCurrentDestination();
            assertNotNull(destination);
            assertEquals(destination.getId(), R.id.loginFragment);
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

此类->Lambda 表达式需要compileOptions.sourceCompatibility JavaVersion.VERSION_1_8build.gradle. 并且可以Activityfragment.getActivity()(注意,这不是通常的)获得。


Jam*_*rog 8

官方android文档目前提供了一些细节,但没有\xe2\x80\x99t很多示例。

\n\n

在您的测试中,您可以使用 Mockito 提供模拟 NavController,并使用它来验证应用程序的交互。

\n\n

例如,要测试应用程序在用户单击按钮时是否正确地将用户导航到特定屏幕,您的测试需要验证此片段是否使用NavController.navigate()所需的操作进行调用。

\n\n

使用 FragmentScenario、Espresso 和 Mockito 的组合,您可以重新创建测试此场景所需的条件,如下所示:

\n\n
@RunWith(AndroidJUnit4::class)\nclass FirstScreenTest {\n\n    @Test\n    fun testNavigationToSecondScreen() {\n        // Create a mock NavController\n        val mockNavController = mock(NavController::class.java)\n\n        // Create a graphical FragmentScenario for the FirstScreen\n        val firstScenario = launchFragmentInContainer<FirstScreen>()\n\n        // Set the NavController property on the fragment\n        firstScenario.onFragment { fragment ->\n            Navigation.setViewNavController(fragment.requireView(), mockNavController)\n        }\n\n        // Verify that performing a click prompts the correct Navigation action\n        onView(ViewMatchers.withId(R.id.button)).perform(ViewActions.click())\n        verify(mockNavController).navigate(R.id.action_first_screen_to_second_screen)\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

  • 不要只是发布链接作为答案。链接过期或链接的内容可能会更改。相反,尝试解释它并给出一个简单的解决方案 (3认同)