Как писать тесты для Android Navigation Controller

Я использую новый контроллер навигации, который сейчас находится в альфа-версии. Он отлично работает, но я не могу найти какое-либо документацию или образец приложения, чтобы увидеть, как это делается тестирование. Также Google опубликовал библиотеку android.arch.navigation:navigation-testing для тестирования навигации, но опять же нет документации.

Любая помощь или предложение будут оценены.

19
0
3 201
2

Ответы 2

Официальная документация по Android в настоящее время содержит некоторые подробности, но примеров немного.

В своем тесте вы можете предоставить фиктивный NavController с помощью Mockito и использовать его для проверки взаимодействия вашего приложения.

Например, чтобы проверить, правильно ли приложение перемещает пользователя к определенному экрану, когда пользователь нажимает кнопку, ваш тест должен убедиться, что этот фрагмент вызывает NavController.navigate() с желаемым действием.

Используя комбинацию FragmentScenario, Espresso и Mockito, вы можете воссоздать условия, необходимые для тестирования этого сценария, как показано ниже:

@RunWith(AndroidJUnit4::class)
class FirstScreenTest {

    @Test
    fun testNavigationToSecondScreen() {
        // Create a mock NavController
        val mockNavController = mock(NavController::class.java)

        // Create a graphical FragmentScenario for the FirstScreen
        val firstScenario = launchFragmentInContainer<FirstScreen>()

        // Set the NavController property on the fragment
        firstScenario.onFragment { fragment ->
            Navigation.setViewNavController(fragment.requireView(), mockNavController)
        }

        // Verify that performing a click prompts the correct Navigation action
        onView(ViewMatchers.withId(R.id.button)).perform(ViewActions.click())
        verify(mockNavController).navigate(R.id.action_first_screen_to_second_screen)
    }
}

Не размещайте ссылку просто в качестве ответа. Срок действия ссылок истекает, или содержание ссылки может измениться. Вместо этого попробуйте объяснить это и дать простое решение

Stephan Hogenboom 04.12.2019 17:28

@StephanHogenboom Извини! Я обновил свой ответ - надеюсь, он более уместен :)

James Olrog 04.12.2019 18:00

Если вы не возражаете, я спрошу: отказались ли вы от шляп Winter Bash (нажали кнопку «Ненавижу шляпы»)?

gparyani 19.12.2019 13:41

Вот мой недавний пример с FragmentScenario и 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"
}

И инструментальный тест:

/**
 * 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);
        });
    }
}

Такие лямбда-выражения -> требуют, чтобы compileOptions.sourceCompatibility JavaVersion.VERSION_1_8 был установлен в build.gradle. А Activity можно получить от fragment.getActivity() (будьте осторожны, он не обычный).

Как вызвать setViewNavController, если ваш Fragment НЕ имеет связанного представления, а вместо этого неявно извлекает его через родительский Fragment?

tim 05.06.2021 12:35

Другие вопросы по теме