Использование FragmentScenario с вложенными NavHostFragments делает невозможным проверку определенных переходов во время тестирования.
В моем приложении у меня есть MainActivity, который содержит NavHostFragment. Этот NavHostFragment используется для отображения фрагментов, некоторые из которых имеют свои собственные NavHostFragments.
Например, MainActivity содержит NavHostFragment1, который указывает на main_nav_graph.xml, который по умолчанию отображает FragmentA. Пользователь взаимодействует с фрагментом A для запуска MasterDetailFragment, который содержит NavHostFragment2.
Итак, main_nav_graph.xml выглядит так: FragmentA -> MasterDetailFragment
Когда пользователь находится в MasterDetailFragment и нажимает кнопку возврата, мы перехватываем обратное нажатие и показываем пользователю CancelConfirmationFragment. Если пользователь подтверждает, что он хочет покинуть экран, нам нужно выполнить переход обратно к FragmentA. Вот тут-то и получается немного сложнее.
Если я просто слепо использую функцию findNavController() из CancelConfirmationFragment, тогда он получит дескриптор вложенного NavHostFragment (NavHostFragment2) и попытается выполнить навигацию с ним, что будет неверным. Что мне действительно нужно, так это получить дескриптор NavHostFragment1 в MainActivity. Для этого я создал интерфейс, который реализует MainActivity, который при вызове возвращает NavHostFragment MainActivity.
// This gets a handle to MainActivity's navController
(requireActivity() as HasNavController).getNavController().popBackStack(R.id.fragment_a, false)
Когда я вручную тестирую свое приложение, это отлично работает. Однако, когда я запускаю инструментальные тесты на MasterDetailFragment изолированно, я сталкиваюсь с проблемой, потому что на самом деле у меня нет экземпляра MainActivity, содержащего мой MasterDetailFragment, у меня есть экземпляр Activity, который создает FragmentScenario, который не реализует мой специальный интерфейс.
Чтобы мои инструментальные тесты заработали, я прекращаю использовать FragmentScenario и создаю Activity специально для теста под названием FakeMainActivity. FakeMainActivity будет иметь NavHostFragment и будет реализовывать специальный интерфейс, который реализует MainActivity. В тестовой настройке я мог бы затем передать фиктивный навигационный контроллер в FakeMainActivity и убедиться, что, когда пользователь подтверждает, что он хочет вернуться назад, фиктивный навигационный контроллер имеет определенный вызов, сделанный на нем. Это кажется подходящим решением, однако я чувствую, что могу пройти в любом пункте навигации (даже в том, до которого невозможно добраться), и тест пройдет, но на самом деле это не так, поэтому я даже не уверен, что тест действительно стоит написать.
Я принципиально неправильно использую либо компоненты навигации, либо FragmentScenario?
Это просто сложная вещь для тестирования в целом?
Должен ли я просто тестировать такую навигацию (переход от одного навигационного хоста к другому) в неизолированном тесте, таком как тест e2e или тест интеграции между двумя фрагментами?
Было бы разумно, если бы FragmentScenario мог принимать аргумент, который позволяет запускать настраиваемое Activity вместо Activity, которое предоставляет FragmentScenario?