Kotlin for Android Developers
Download 1.04 Mb. Pdf ko'rish
|
Kotlin for Android Developers Learn Kotlin the Easy Way While Developing an Android App ( PDFDrive )
27.2 Instrumentation tests
Instrumentation tests are a bit different. They are normally used to test UI interactions, where we need an Application instance to be running by the time the tests are executed. To do this, we’ll need to deploy the App and run the tests in a device. This type of tests must be included in the androidTest folder, and we must change ‘Test Artifact’ to ‘Android Instrumentation Tests’ in ‘Build Variants’ panel. The official library to implement instrumentation tests is Espresso³⁰ , which will help us easily navigate through our App by writing Action s, and filter and check results using ViewMatcher s and Matcher s. ³⁰ https://google.github.io/android-testing-support-library/ 27 Testing your App 137 The configuration is a bit harder than the previous one. We need a bunch of extra libraries and Gradle configuration. The good thing is that Kotlin doesn’t add any extra overhead, so if you already know how to configure Espresso, it will be easy for you. First, specify the test runner in defaultConfig : 1 defaultConfig { 2 ... 3 testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 4 } Once you’ve dealt with the runner, it’s time to add the rest of the dependencies, this time using androidTestCompile . That way, these libraries only will be added when we compile to run the instrumentation tests: 1 dependencies { 2 ... 3 androidTestCompile "com.android.support:support-annotations:$support_version" 4 androidTestCompile "com.android.support.test:runner:0.4.1" 5 androidTestCompile "com.android.support.test:rules:0.4.1" 6 androidTestCompile "com.android.support.test.espresso:espresso-core:2.2.1" 7 androidTestCompile ("com.android.support.test.espresso:espresso-contrib:2.2.\ 8 1"){ 9 exclude group: 'com.android.support', module: 'appcompat' 10 exclude group: 'com.android.support', module: 'support-v4' 11 exclude module: 'recyclerview-v7' 12 } 13 } I don’t want to spend much time talking about this, but here it is a brief reasoning about why you need these libraries: • support-annotations : it’s required by some of the other libraries. • runner : It’s the test runner, the one we specified in defaultConfig . • rules : Includes some rules that help tests inflate and launch the activities. We’ll use a rule in our examples. • espresso-core : the basic implementation of Espresso, the library that makes instrument tests easier. • espresso-contrib : it adds some extra features, such as RecyclerView testing support. We have to exclude some of its dependencies, because we already have them in the project, and tests will crash otherwise. 27 Testing your App 138 Let’s now create a simple example. The test will click on the first row of the forecast list, and check that it can find a view with the id R.id.weatherDescription . This view is in the DetailActivity , which means we are testing that we successfully navigated to the detail after clicking on a view inside the RecyclerView . 1 class SimpleInstrumentationTest { 2 3 @get:Rule 4 val activityRule = ActivityTestRule(MainActivity::class.java) 5 6 ... 7 } First we need to specify that it’s being run using AndroidJUnit4 . Then, create an activity rule, that will instantiate the activity the test will use. In Java, you would annotate the field using @Rule . But as you now, fields and properties are not the same, so if you use just that, the execution will fail because the access to the field inside the property is not public. What you need to do is to annotate the getter. Kotlin allows to do that by specifying get or set before the name of the rule. In this case, just write @get:Rule . After that, we are ready to create our first test: 1 @Test fun itemClick_navigatesToDetail() { 2 onView(withId(R.id.forecastList)).perform( 3 RecyclerViewActions 4 .actionOnItemAtPosition 5 onView(withId(R.id.weatherDescription)) 6 .check(matches(isAssignableFrom(TextView::class.java))) 7 } The function is annotated with @Test , the same way we did with unit tests. We can start using Espresso in the body of the test. It first performs a click over the first position of the recycler. Then, it checks that it can find a view with an specific id and that it is an instance of TextView . To run the test, click on the top ‘Run configurations’ dropdown and choose ‘Edit Configurations…’. Press the ‘+’ icon, select ‘Android Tests’, and choose the app module. Now, in target device, choose the target you prefer. Click ‘OK’ and then run. You should see how the App is started in your device, and the test clicks on the first position, opens the detail activity and closes the App again. Now we are going to do a more difficult one. The test will open the overflow from the Toolbar , click on Settings action, change the city code and check that the Toolbar title has changed to the corresponding one. 27 Testing your App 139 1 @Test fun modifyZipCode_changesToolbarTitle() { 2 openActionBarOverflowOrOptionsMenu(activityRule.activity) 3 onView(withText(R.string.settings)).perform(click()) 4 onView(withId(R.id.cityCode)).perform(replaceText("28830")) 5 pressBack() 6 onView(isAssignableFrom(Toolbar::class.java)) 7 .check(matches( 8 withToolbarTitle(`is`("San Fernando de Henares (ES)")))) 9 } What the test exactly does is: • It first opens the overflow by using openActionBarOverflowOrOptionsMenu . • It then finds a view with the Settings text, and performs a click on it. • After that, the settings activity is opened, so it will look for the EditText and replace the old city code with a new one. • It presses the back button. This will save the new value inside the preferences, and close the activity. • As onResume is executed in MainActivity , the request is performed again. This will retrieve the forecast of the new city. • Last line will check the Toolbar title and see whether it matches with the proper value. There is not a default matcher to check Toolbar title, but Espresso is easy to extend, so we can create a new matcher which implements the check: 1 private fun withToolbarTitle(textMatcher: Matcher 2 object : BoundedMatcher 3 4 override fun matchesSafely(toolbar: Toolbar): Boolean { 5 return textMatcher.matches(toolbar.title) 6 } 7 8 override fun describeTo(description: Description) { 9 description.appendText("with toolbar title: ") 10 textMatcher.describeTo(description) 11 } 12 } The matchesSafely function is the place where the check is done, while the describeTo function adds some information about the matcher. This chapter has been specially interesting, because we’ve seen how Kotlin is perfectly compatible with both unit and integration tests and is able to interoperate with the testing libraries. Take a look at the code and run the tests by yourself. |
Ma'lumotlar bazasi mualliflik huquqi bilan himoyalangan ©fayllar.org 2024
ma'muriyatiga murojaat qiling
ma'muriyatiga murojaat qiling