Эспрессо — это фреймворк, который предоставляет простой API для тестирования пользовательского интерфейса программы.
Начиная с версии 2.0, эспрессо является частью Android Support Repository, что делает добавление Espresso в проект более легким.
Но, прежде чем перескакивать к API Эспрессо , давайте рассмотрим чем этот фреймворк отличается от других:
1) API тестов Espresso выглядит как обычный английский текст, что позволяет быстро научиться работать с ним.
2) Имеет маленький API
3) Espresso быстро запускается
4) Поддержка Gradle+Android Studio
Добавляем Espresso в проект
1. Прежде всего мы должны установить Android Support Repository
2) Добавьте зависимости в файл build.gradle:
dependencies { androidTestCompile 'com.android.support.test:testing-support-lib:0.1' androidTestCompile 'com.android.support.test.espresso:espresso-core:2.0' }
3) Наконец, добавьте команду запуска тестов в defaultConfig:
android { defaultConfig { // .... testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } }
Главные компоненты в Espresso
Espresso состоит из трех основных компонентов:
- ViewMatchers – позволяетнайти View на экране
- ViewActions – позволяет взаимодействовать с View
- ViewAssertions — проверяет состояние View
Для простоты, вы можете использовать эти шпаргалки:
• ViewMatchers — «что-то» найти
• ViewActions — «сделать что-то»
• ViewAssertions — «что-то» проверить
Например, когда вам нужно будет что-то проверить (как, некоторый текст отображается на экране), вы будете знать, что для этого вам понадобится ViewAssertion.
Ниже приведен пример теста Espresso и показано расположение главных компонентов:
Простой тест с использованием onView()
Предположим, у нас есть приложение, где пользователь должен ввести свое имя.
После того как он вводит имя, он нажимает на кнопку «Далее» и перенаправляется на другую активити, на которой отображается приветственное сообщение.
Напишем тест для этого приложения:
// locate the view with id "user_name" and type the text "John" onView(withId(R.id.user_name)).perform(typeText("John")); // locate the view with id "next" and click on it onView(withId(R.id.next)).perform(click()); // locate the view with id "greeting_message" and check its text is equal with "Hello John!" onView(withId(R.id.greeting_message)).check(matches(withText("Hello John!")));
Обратите внимание, что мы не указываем явно какие с какими View мы взаимодействуем (EditText или Button), мы просто говорим, что мы ищем View с конкретным идентификатором.
Кроме того, при нажатии на кнопку «Далее» а также при проверке текста, мы не должны писать специальный код, чтобы рассказать эспрессо, что мы перемещаться на другую активити.
Теперь, если мы действительно хотим запустить этот тест, то он должен быть помещен в класс. В Gradle, тесты хранятся в папке: ваше_приложение/src/androidTest/java.
Это пример класса теста, и его основные характеристики:
Простой тест с использованием onData()
Всякий раз, когда у вас есть ListView, GridView, Spinner или другие View, основанные адаптере, вы должны будете использовать метод onData () для того, чтобы взаимодействовать с элементом из этого списка. Метод onData () ориентирован на непосредственно данные, предоставленные вашим адаптером. Что это значит, мы сейчас увидим:
Представим, что у нас есть приложение, в котором мы должны выбрать страну из Spiner’а. При выборе пункта название выбранного пункта отображается рядом со Spiner’ом:
А вот тест для тестирования этого приложения:
// locate the view with id "country_spinner" and click on it onView(withId(R.id.country_spinner)).perform(click()); // match an item that is a String and is equal with whatever value the COUNTRY constant is initialized, then click on it. onData(allOf(is(instanceOf(String.class)), is(COUNTRY))).perform(click()); // locate the view with id "selected_country" and check its text is equal with COUNTRY onView(withId(R.id.selected_country)).check(matches(withText("selected: " + COUNTRY)));
Как мы видим, Spinner основан на массиве строк. Если вместро строк используется собственный класс, то мы должны указать на это. Рассмотрим тест на примере списка книг:
Вот так теперь выглядит тест:
onData(allOf(is(instanceOf(Book.class)), withBookTitle(BOOK_TITLE))).perform(click());
Откуда взялся метод withBookTitle вы можете посмотреть в исходниках на GitHub, ссылка на который расположена в конце статьи.
DataInteractions
Espresso имеет несколько полезных методов для взаимодействия с данными.
atPosition() – может быть полезен, когда элементы расположены в определенном порядке и вы точно знаете на какой позиции находится данный элемент.
onData(…).atPosition(2).perform(click());
inRoot() — используется при не стандартных окнах. Один из сценариев использования это функция автозаполнения (подсказки) у EditText. Пример:
onView(withText("AutoCompleteText")) .inRoot(withDecorView(not(is(getActivity().getWindow().getDecorView())))) .check(matches(isDisplayed()));
onChildView() – этот DataInteraction уточнить запрос, позволяя взаимодкействовать с конкретным View из списка. Например, у нас есть список элементов и у каждого элемента есть кнопка удаления. Вы хотите нажать кнопку «Удалить» у конкретного пункта в списке:
onData(withBookTitle("My Book")) .onChildView(withId(R.id.book_delete)).perform(click());
inAdapterView() — нужен для взаимодействия с конкретным классом адаптера. По умолчанию Espresso работает со всеми видами адаптеров. Это может быть полезно при работе с ViewPager’ом или Fragment’ами, когда вам нужно взаимодействовать с тем адаптером, который отображается на экране или же, если на вашем экране больше одного адаптера. Пример:
onData(withBookTitle("My Book")) .inAdapterView(allOf(isAssignableFrom(AdapterView.class), isDisplayed())) .perform(click());
Espresso и RecycleView
RecyclerView — это UI-компонент, предназначенный для визуализации набора данных в виде ListView или GridView и призван заменить их обоих. RecycleView не является наследником AdapterView, поэтому мы больше не сможем использовать метод onData() для взаимодействия с элементами списка.
К счастью, есть класс, называемый RecyclerViewActions, который представляет из себя небольшой API для работы на RecyclerView. RecyclerViewActions является частью отдельной библиотеки, которая называется espresso-contrib, которая также должна быть добавлена к build.gradle:
dependencies { // … androidTestCompile('com.android.support.test.espresso:espresso-contrib:2.0'); }
Уберем некоторые библиотеки из зависимостей, чтобы избежать конфликтов:
dependencies { // … androidTestCompile('com.android.support.test.espresso:espresso-contrib:2.0') { exclude group: 'com.android.support', module: 'appcompat' exclude group: 'com.android.support', module: 'support-v4' exclude module: 'recyclerview-v7' } }
Выберем пункт из списка:
onView(withId(R.id.recyclerView)) .perform(RecyclerViewActions.actionOnItemAtPosition(0, click()));
Или нажмем на View из пункта:
onView(withId(R.id.recyclerView)) .perform(RecyclerViewActions.actionOnItem( hasDescendant(withText(BOOK_TITLE)), click()));
Примеры тестов с Espresso на GitHub: https://github.com/vgrec/EspressoExamples
Источник: Introduction to Android Espresso