ऐप्लिकेशन शिप करने से पहले, उसके नेविगेशन लॉजिक की जांच करना ज़रूरी है. इससे यह पुष्टि की जा सकती है कि आपका ऐप्लिकेशन आपकी उम्मीद के मुताबिक काम कर रहा है या नहीं.
नेविगेशन कॉम्पोनेंट, नेविगेशन को मैनेज करने का सारा काम
डेस्टिनेशन, आर्ग्युमेंट पास करना, और
FragmentManager
.
इन क्षमताओं की पहले ही अच्छी तरह से जांच कर ली गई है, इसलिए इनकी ज़रूरत नहीं है
उन्हें फिर से अपने ऐप्लिकेशन में जोड़ सकते हैं. हालांकि, टेस्ट करना ज़रूरी है कि इंटरैक्शन
आपके फ़्रैगमेंट में ऐप्लिकेशन के खास कोड और उनके
NavController
.
इस गाइड में नेविगेशन के कुछ आम तरीकों और उनकी जांच करने के तरीके के बारे में बताया गया है.
फ़्रैगमेंट नेविगेशन की जांच करना
फ़्रैगमेंट इंटरैक्शन को NavController
के साथ अकेले टेस्ट करने के लिए,
नेविगेशन 2.3 और उसके बाद के वर्शन में
TestNavHostController
जो मौजूदा डेस्टिनेशन को सेट करने के लिए एपीआई उपलब्ध कराता है और पिछले पेज की पुष्टि करता है
इसके बाद स्टैक करें
NavController.navigate()
कार्रवाइयां.
आप
आपके ऐप्लिकेशन मॉड्यूल की build.gradle
फ़ाइल में, नीचे दी गई डिपेंडेंसी का इस्तेमाल किया जा रहा है:
ग्रूवी
dependencies { def nav_version = "2.8.0" androidTestImplementation "androidx.navigation:navigation-testing:$nav_version" }
Kotlin
dependencies { val nav_version = "2.8.0" androidTestImplementation("androidx.navigation:navigation-testing:$nav_version") }
मान लें कि आपको सवाल-जवाब वाला कोई गेम बनाना है. गेम इनसे शुरू होता है: title_screen और उपयोगकर्ता के क्लिक करने पर in_game स्क्रीन पर ले जाता है खेलना.
title_screen दिखाने वाला फ़्रैगमेंट कुछ ऐसा दिख सकता है:
Kotlin
class TitleScreen : Fragment() { override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ) = inflater.inflate(R.layout.fragment_title_screen, container, false) override fun onViewCreated(view: View, savedInstanceState: Bundle?) { view.findViewById<Button>(R.id.play_btn).setOnClickListener { view.findNavController().navigate(R.id.action_title_screen_to_in_game) } } }
Java
public class TitleScreen extends Fragment { @Nullable @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { return inflater.inflate(R.layout.fragment_title_screen, container, false); } @Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { view.findViewById(R.id.play_btn).setOnClickListener(v -> { Navigation.findNavController(view).navigate(R.id.action_title_screen_to_in_game); }); } }
यह जांचने के लिए कि ऐप्लिकेशन उपयोगकर्ता को in_game स्क्रीन पर सही तरीके से नेविगेट करता है या नहीं
अगर उपयोगकर्ता चलाएं पर क्लिक करता है, तो आपके टेस्ट को इस बात की पुष्टि करनी होगी कि यह फ़्रैगमेंट
NavController
को सही ढंग से R.id.in_game
स्क्रीन पर ले जाता है.
FragmentScenario
, Espresso, के कॉम्बिनेशन का इस्तेमाल करके,
और TestNavHostController
, तो टेस्ट के लिए ज़रूरी शर्तों को फिर से बनाया जा सकता है
जैसा कि नीचे दिए गए उदाहरण में दिखाया गया है:
Kotlin
@RunWith(AndroidJUnit4::class) class TitleScreenTest { @Test fun testNavigationToInGameScreen() { // Create a TestNavHostController val navController = TestNavHostController( ApplicationProvider.getApplicationContext()) // Create a graphical FragmentScenario for the TitleScreen val titleScenario = launchFragmentInContainer<TitleScreen>() titleScenario.onFragment { fragment -> // Set the graph on the TestNavHostController navController.setGraph(R.navigation.trivia) // Make the NavController available via the findNavController() APIs Navigation.setViewNavController(fragment.requireView(), navController) } // Verify that performing a click changes the NavController’s state onView(ViewMatchers.withId(R.id.play_btn)).perform(ViewActions.click()) assertThat(navController.currentDestination?.id).isEqualTo(R.id.in_game) } }
Java
@RunWith(AndroidJUnit4.class) public class TitleScreenTestJava { @Test public void testNavigationToInGameScreen() { // Create a TestNavHostController TestNavHostController navController = new TestNavHostController( ApplicationProvider.getApplicationContext()); // Create a graphical FragmentScenario for the TitleScreen FragmentScenario<TitleScreen> titleScenario = FragmentScenario.launchInContainer(TitleScreen.class); titleScenario.onFragment(fragment -> // Set the graph on the TestNavHostController navController.setGraph(R.navigation.trivia); // Make the NavController available via the findNavController() APIs Navigation.setViewNavController(fragment.requireView(), navController) ); // Verify that performing a click changes the NavController’s state onView(ViewMatchers.withId(R.id.play_btn)).perform(ViewActions.click()); assertThat(navController.currentDestination.id).isEqualTo(R.id.in_game); } }
ऊपर दिया गया उदाहरण, TestNavHostController
का एक इंस्टेंस बनाता है और उसे असाइन करता है
फ़्रैगमेंट तक पहुंच जाएंगे. इसके बाद यह यूज़र इंटरफ़ेस (यूआई) को चलाने के लिए Espresso का इस्तेमाल करती है और पुष्टि करती है कि
नेविगेशन की ज़रूरी कार्रवाई की गई है.
बिलकुल असली NavController
की तरह ही, शुरू करने के लिए आपको setGraph
को कॉल करना होगा
TestNavHostController
. इस उदाहरण में, जिस खंड की जांच की जा रही है, वह था
हमारे ग्राफ़ का शुरुआती गंतव्य होता है. TestNavHostController
यह देता है:
setCurrentDestination
तरीका है जिससे आप मौजूदा डेस्टिनेशन (और वैकल्पिक रूप से,
आर्ग्युमेंट के तौर पर शामिल करना होगा), ताकि NavController
टेस्ट शुरू होने से पहले सही स्थिति सेट करें.
NavHostFragment
का इस्तेमाल करने वाले NavHostController
इंस्टेंस के उलट,
TestNavHostController
, मौजूदा navigate()
को ट्रिगर नहीं करता है
व्यवहार (जैसे कि FragmentTransaction
जो FragmentNavigator
करता है)
जब आप navigate()
को कॉल करते है - तो यह केवल
TestNavHostController
.
फ़्रैगमेंट स्थिति से नेविगेशन यूआई की जांच करें
पिछले उदाहरण में, titleScenario.onFragment()
को दिया गया कॉलबैक
तब कॉल किया जाता है, जब फ़्रैगमेंट अपने लाइफ़साइकल की मदद से
RESUMED
राज्य. तब तक, फ़्रैगमेंट का व्यू बन चुका होगा और अटैच हो चुका होगा,
इसलिए, लाइफ़साइकल में शायद सही तरीके से टेस्ट न किया जा सके. उदाहरण के लिए,
आपके फ़्रैगमेंट में व्यू वाले NavigationUI
, जैसे कि Toolbar
को कंट्रोल किया जाता है
आपके फ़्रैगमेंट के आधार पर, अपने NavController
की मदद से, सेटअप करने के तरीकों को कॉल किया जा सकता है
फ़्रैगमेंट RESUMED
स्थिति तक पहुंच जाता है. इसलिए, आपको अपना लक्ष्य सेट करने का
लाइफ़साइकल में TestNavHostController
पहले.
जिस फ़्रैगमेंट के पास अपने Toolbar
का मालिकाना हक है उसे इस तरह लिखा जा सकता है:
Kotlin
class TitleScreen : Fragment(R.layout.fragment_title_screen) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { val navController = view.findNavController() view.findViewById<Toolbar>(R.id.toolbar).setupWithNavController(navController) } }
Java
public class TitleScreen extends Fragment { public TitleScreen() { super(R.layout.fragment_title_screen); } @Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { NavController navController = Navigation.findNavController(view); view.findViewById(R.id.toolbar).setupWithNavController(navController); } }
यहां हमें चाहिए कि onViewCreated()
को कॉल करते समय बनाया गया NavController
.
onFragment()
के पिछले तरीके का इस्तेमाल करने से, हमारी TestNavHostController
सेट हो जाएगी
बिलिंग साइकल में बहुत देर हो गई है, जिसकी वजह से findNavController()
कॉल फ़ेल हो गया.
FragmentScenario
ऑफ़र करता है
FragmentFactory
इंटरफ़ेस, जिसका इस्तेमाल लाइफ़साइकल इवेंट के लिए कॉलबैक रजिस्टर करने के लिए किया जा सकता है. यह काम कर सकता है
पाने के लिए Fragment.getViewLifecycleOwnerLiveData()
के साथ जोड़ा जाएगा
कॉलबैक जो तुरंत onCreateView()
के बाद आता है, जैसा कि यहां दिखाया गया है
उदाहरण:
Kotlin
val scenario = launchFragmentInContainer { TitleScreen().also { fragment -> // In addition to returning a new instance of our Fragment, // get a callback whenever the fragment’s view is created // or destroyed so that we can set the NavController fragment.viewLifecycleOwnerLiveData.observeForever { viewLifecycleOwner -> if (viewLifecycleOwner != null) { // The fragment’s view has just been created navController.setGraph(R.navigation.trivia) Navigation.setViewNavController(fragment.requireView(), navController) } } } }
Java
FragmentScenario<TitleScreen> scenario = FragmentScenario.launchInContainer( TitleScreen.class, null, new FragmentFactory() { @NonNull @Override public Fragment instantiate(@NonNull ClassLoader classLoader, @NonNull String className, @Nullable Bundle args) { TitleScreen titleScreen = new TitleScreen(); // In addition to returning a new instance of our fragment, // get a callback whenever the fragment’s view is created // or destroyed so that we can set the NavController titleScreen.getViewLifecycleOwnerLiveData().observeForever(new Observer<LifecycleOwner>() { @Override public void onChanged(LifecycleOwner viewLifecycleOwner) { // The fragment’s view has just been created if (viewLifecycleOwner != null) { navController.setGraph(R.navigation.trivia); Navigation.setViewNavController(titleScreen.requireView(), navController); } } }); return titleScreen; } });
इस तकनीक का इस्तेमाल करने पर, NavController
उपलब्ध हो जाता है
onViewCreated()
को कॉल किया गया है. इससे फ़्रैगमेंट को NavigationUI
तरीकों का इस्तेमाल करने की अनुमति मिली है
वह भी क्रैश हो गया.
पिछली गतिविधियों वाली एंट्री के साथ इंटरैक्शन की जांच करना
बैक स्टैक एंट्री के साथ इंटरैक्ट करते समय,
TestNavHostController
की मदद से, कंट्रोलर को अपने डिवाइस से कनेक्ट किया जा सकता है
इसके हिसाब से LifecycleOwner
, ViewModelStore
, और OnBackPressedDispatcher
की जांच करें
इनहेरिट किए गए एपीआई का इस्तेमाल करके
NavHostController
.
उदाहरण के लिए, ऐसे फ़्रैगमेंट की जांच करते समय जो
नेविगेशन के स्कोप वाला ViewModel,
तुम्हें कॉल करना होगा
setViewModelStore
को TestNavHostController
पर करें:
Kotlin
val navController = TestNavHostController(ApplicationProvider.getApplicationContext()) // This allows fragments to use by navGraphViewModels() navController.setViewModelStore(ViewModelStore())
Java
TestNavHostController navController = new TestNavHostController(ApplicationProvider.getApplicationContext()); // This allows fragments to use new ViewModelProvider() with a NavBackStackEntry navController.setViewModelStore(new ViewModelStore())
संबंधित विषय
- इंस्ट्रुमेंटेड यूनिट टेस्ट बनाएं - अपने इंस्ट्रुमेंटेड टेस्ट सुइट को सेटअप करने और Android पर टेस्ट चलाने का तरीका जानें डिवाइस.
- Espresso - अपने ऐप्लिकेशन के यूज़र इंटरफ़ेस (यूआई) की जांच करें Espresso के साथ संपर्क करें.
- AndroidX टेस्ट के साथ JUnit4 के नियम - JUnit 4 का इस्तेमाल करें को कम करने और ज़्यादा सुविधा देने के लिए, AndroidX की जांच लाइब्रेरी के साथ-साथ नियमों को लागू करना भी बॉयलरप्लेट कोड का इस्तेमाल कर सके.
- अपने ऐप्लिकेशन के फ़्रैगमेंट की जांच करें -
FragmentScenario
की मदद से अपने ऐप्लिकेशन के फ़्रैगमेंट की जांच करने का तरीका जानें. - AndroidX Test के लिए प्रोजेक्ट सेट अप करें - जानें AndroidX का इस्तेमाल करने के लिए, अपने ऐप्लिकेशन की प्रोजेक्ट फ़ाइलों में ज़रूरी लाइब्रेरी का एलान कैसे करें परीक्षण.