series
- Introduction to Android Test
- How to Test ViewModel and LiveData
- How to Test Doubles as a Repository
preface
The first three articles covered how to write unit tests. Starting with this article, we will cover integration tests
Fragments are closely related to the ViewModel, and we need to make sure that the ViewModel updates the UI at the appropriate time. So how do we test this part?
Udacity Advanced Android with Kotlin-Lesson 11-5.2 Testing: Intro to Test Doubles & Dependency Injection
Fragment integration test
For integration testing on the architecture below, we need to mask as much irrelevant code as possible
For example, we can use empty Activity, which contains no fragment or other code for the activity. For the data layer, use Test Doubles instead
This allows you to focus on the fragment and ViewModel code
FragmentScenario
The FragmentScenario and ActivityScenario apis in AndroidX Test can help you when you need to test activities and fragments
The introduction of
debugImplementation "androidx.fragment:fragment-testing:$fragmentVersion"
implementation "androidx.test:core:$androidXTestCoreVersion"
Copy the code
use
These apis are used to provide fragments and activities for testing, and you can control their startup and lifecycle status
The following code is used to start the fragment and pass the bundle
val bundle = Bundle().apply { putString("username"."Flywith24")}val scenario = launchFragmentInContainer<RepoListFragment>(bundle, R.style.AppTheme)
Copy the code
Call if you want to control the fragment’s life-cycle state
scenario.moveToState(Lifecycle.State.CREATED)
Copy the code
❝
Since FragmentScenario is part of AndroidX Test, it can be used in both local test and instrumented test
❞
Espresso
If you want to test UI components in Android, you can use the Espresso library, which allows you to use Views and check their state
The introduction of
androidTestImplementation "androidx.test.espresso:espresso-core:$espressoVersion"
androidTestImplementation "androidx.test.espresso:espresso-contrib:$espressoVersion"
Copy the code
use
An Espresso has four basic parts
-
“Static Espresso method“
-
“ViewMatchers“
-
“ViewAction“
-
“ViewAssertion“
OnView () is a common static method in Espresso, which means that the view will be manipulated next
The job of ViewMatches is to find the view, using the withId() method above, matching the view with its ID. There are other matching methods, such as withText
❝
Note: Ensure that ViewMatches matches only one view, otherwise an AmbiquousviewMatcher Exception will be thrown
❞
ViewAction is the action performed by the view, in this case the Click method
ViewAssertion can be used to determine whether the view is in the expected state
❝
Tips: To improve responsiveness, you can turn the animation off in the developer option
❞
Mockito
Mock
We introduce the type of Test Doubles in The concept of Test Doubles and how to Test Repository, and we mainly introduce Fake. Today, we introduce another type of test Doubles: mocks
Unlike Fake, mocks focus on tracing method calls, which may be abstract, but let’s take an example
As shown above, a method is called that changes the UI (update text)
If you Mock, verify that the method to update the text is called correctly
Without a Mock, we usually verify that the text in the TextView is as expected
The introduction of Mockito
To Mock tests, we need to introduce the Mockito library
androidTestImplementation "Org. Mockito: mockito - core: 2.25.0"
androidTestImplementation "Com. Linkedin. Dexmaker: dexmaker - mockito: 2.12.1." "
Copy the code
Some of you may ask, is there any scenario where you need to Mock?
Here is a good example to test the fragment jump using navigation
Testing Navigation
We have a HostFragment that has a button inside it that you can click to jump to the RepoListFragment and pass the user name there
Let’s test this part of the jump
The first fragment is provided first
// GIVEN Displays fragment
val scenario = launchFragmentInContainer<HostFragment>(Bundle(), R.style.AppTheme)
Copy the code
Since we are using Navigation, we also need navigationController
val navController = Mockito.mock(NavController::class.java)scenario.onFragment { Navigation.setViewNavController(it.view!! , navController) }Copy the code
Finally, we perform button clicking and verify that the navigation jump and parameter transfer meet the requirements
// WHEN click the search button
onView(withId(R.id.button)).perform(click())
// THEN repolist interface
verify(navController).navigate(HostFragmentDirections.actionHostFragmentToRepoListFragment("Flywith24"))
Copy the code
About me
I am a Fly_with24
-
The Denver nuggets
-
Jane’s book
-
Github