For the More Curious: Integration Testing

We said earlier that SoundViewModelTest is a unit test and that your other option was to create an integration test. So: What is an integration test?

In a unit test, the item under test is an individual class. In an integration test, the item under test is a section of your app, with many pieces working together. Both of these tests are important and serve different purposes. Unit tests ensure correct behavior of each class unit and your expectations of how these units will interact with each other. Integration tests verify that the individually tested pieces actually do integrate together properly and function as expected.

Integration tests can be written for non-UI parts of your app, such as database interactions, but on Android they are most commonly written to test the app at the UI level by interacting with its UI and verifying expectations. They are usually written screen by screen. For example, you might test that when the MainActivity screen is fired up, the first button displays the name of the first file from sample_sounds: 65_cjipie.

Integration testing against the UI requires framework classes such as activities and fragments. It may also require system services, file systems, and other pieces not available to a JVM test. For this reason, integration tests are most often implemented as instrumentation tests on Android.

Integration tests should pass when the app does what you expect, not when the app is implemented how you expect. Changing the name of a button ID does not affect what the application does, but if you write an integration test that says, Call findViewById(R.id.button) and make sure the button it finds is displaying the right text, that test will break. So instead of using standard Android framework tools like findViewById(Int), UI integration tests are most often written with a UI testing framework that makes it easier to say things like, Make sure there is a button with the text I expect on the screen somewhere.

Espresso is a UI testing framework from Google for testing Android apps. You can include it by adding com.android.support.test.espresso:espresso-core as an androidTestImplementation artifact in your app/build.gradle file. Android Studio includes this dependency by default on new projects.

Once you have Espresso included as a dependency, you can use it to make assertions about an activity you have fired up to test. Here is an example test showing how to assert that a view exists on the screen, using the first sample_sounds test filename:

    @RunWith(AndroidJUnit4::class)
    class MainActivityTest {

        @get:Rule
        val activityRule = ActivityTestRule(MainActivity::class.java)

        @Test
        fun showsFirstFileName() {
            onView(withText("65_cjipie"))
                    .check(matches(isDisplayed()))
        }
    }

A couple of annotations get this code up and running. The @RunWith(AndroidJUnit4.class) annotation up top specifies that this is an Android instrumentation test that might want to work with activities and other Android runtime toys. After that, the @get:Rule annotation on activityRule signals to JUnit that it should fire up an instance of MainActivity before running each test.

With that setup done, you can make assertions about MainActivity in your test. In showsFirstFileName(), the line onView(withText("65_cjipie")) finds a view with the text 65_cjipie on it to perform a test operation on. The call to check(matches(isDisplayed())) after that asserts that the view is visible on the screen – if there is no view with that text, the check will fail. The check(…) function is Espresso’s way to make assertThat(…)-type assertions about views.

Often you will want to click on a view, then make an assertion to verify the result of your click. You can also use Espresso to click on views or otherwise interact with them:

    onView(withText("65_cjipie"))
            .perform(click())

When you interact with a view, Espresso will wait until your application is idle before continuing your test. Espresso has built-in ways of detecting when your UI is done updating, but if you need Espresso to wait longer, you can use a subclass of IdlingResource to signal to Espresso that your app has not settled down quite yet.

For more information about how to use Espresso to manipulate and test the UI, see the Espresso documentation at developer.android.com/​training/​testing/​espresso.

Remember, integration tests and unit tests each serve different purposes. Most people prefer to start with unit tests because they help you define and verify the behavior of the individual parts of your app. Integration tests depend on those individually tested parts and verify that the parts work well together as a whole. Each gives you a distinct, important view of the health of your app, so the best shops do both kinds of testing.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
44.202.128.177