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

Espresso is introduced

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

Close the animation

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


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

navigation

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