name="AppTheme"
parent="
Theme.AppCompat.Light.DarkActionBar
">
name="colorPrimary">@color/colorPrimary
name="colorPrimaryDark">@color/colorPrimaryDark
name="colorAccent">@color/colorAccent
Листинг 20.19. Освобождение BeatBox (BeatBoxFragment.kt)
class MainActivity : AppCompatActivity() {
private lateinit var beatBox: BeatBox
override fun onCreate(savedInstanceState:
Bundle?) {
...
}
override fun onDestroy() {
super.onDestroy()
beatBox.release()
}
...
}
Запустите приложение и убедитесь в том, что оно правильно
работает с новой функцией
release()
. Если при
воспроизведении длительного звука вы повернете устройство
или нажмете кнопку «Назад», звучание должно прекратиться.
Для любознательных: интеграционное тестирование
Как
вы
помните,
упоминавшийся
ранее
тест
SoundViewModelTest
был
модульным.
Также
вам
предоставлялась другая возможность: создать интеграционный
тест. Собственно, что это — интеграционный тест?
При единичном тестировании тестируемое изделие
относится к отдельному классу. В интеграционном тесте
тестируемый субъект — это раздел вашего приложения, многие
части которого работают вместе. Оба эти теста важны и служат
разным целям. Модульные тесты гарантируют правильное
поведение каждого класса и оправдывают ваши ожидания
относительно того, как эти предметы будут взаимодействовать
друг с другом. Интеграционные тесты проверяют, что
протестированные единицы действительно интегрируются
правильно и функционируют так, как ожидается.
Интеграционные тесты используются для частей вашего
приложения, не относящихся к пользовательскому интерфейсу,
например для взаимодействия с базами данных, но на Android
они чаще всего пишутся для тестирования приложения на
уровне пользовательского интерфейса путем взаимодействия с
его интерфейсом и проверки ожиданий. Обычно они пишутся
экран за экраном. Например, вы можете протестировать, что
при запуске экрана
MainActivity
на первой кнопке
отображается имя первого файла из папки
sample_sounds
:
65_cjipie
.
Для интеграционного тестирования по отношению к
пользовательскому интерфейсу требуется наличие классов
фреймворка, таких как activity и фрагменты. Для него также
могут потребоваться системные сервисы, файловые системы и
другие фрагменты, недоступные для JVM-тестирования. По
этой причине интеграционные тесты на Android чаще всего
реализуются в виде инструментальных тестов.
Интеграционные тесты считаются пройденными, когда
приложение делает то, что вы хотите, а не тогда, когда
приложение реализовано так, как вы хотите. Изменение
идентификатора кнопки не повлияет на работу приложения, но
если
вы
напишете
интеграционный
тест
«Вызвать
findViewById(R.id.button)
и убедиться в том, что на
найденной кнопке выводится правильный текст», этот тест не
будет пройден. Итак, вместо стандартных средств Android
(таких как
findViewById(int)
) интеграционные тесты чаще
пишутся во фреймворках тестирования пользовательского
интерфейса, в которых проще выражаются запросы вида
«Убедиться в том, что на экране присутствует кнопка с текстом,
который на ней должен выводиться».
Espresso — фреймворк компании Google для тестирования
пользовательского интерфейса Android-приложений. Чтобы
включить
его,
добавьте
com.android.support.test.espresso:espresso-core
как
артефакт
androidTestImplementation
в
файл
app/build.gradle
.
После добавления в состав зависимостей вы можете
использовать Espresso для проверки условий относительно
запущенной activity. Следующий пример показывает, как
проверить существование на экране представления с первым
именем файла из
sample_sounds
:
@RunWith(AndroidJUnit4::class)
class MainActivityTest {
@get:Rule
val
activityRule
=
ActivityTestRule(MainActivity::class.java)
@Test
fun showsFirstFileName() {
onView(withText("65_cjipie"))
.check(matches(isDisplayed()))
}
}
Работа этого кода основана на паре аннотаций. Аннотация
@RunWith(AndroidJUnit4.class
) указывает, что перед нами
тест Android, который должен работать с activity и другими
средствами времени выполнения Android. После этого
аннотация
@get:Rule
у
activityRule
сообщает JUnit о
необходимости запускать экземпляр
MainActivity
перед
запуском каждого теста.
После предварительной подготовки вы сможете проверять
условия, относящиеся к
MainActivity
, в ваших тестах. В
функции
showsFirstFileName()
строка
onView(withText("65_cjipie"))
находит представление с
текстом
65_cjipie
для выполнения тестовой операции. Вызов
check(matches(isDisplayed()))
проверяет, что такое
представление существует. Если представления с таким текстом
нет, то проверка завершается неудачей. Функция
check(...)
используется
Espresso
для
проверки
условий
типа
assertThat(...)
относительно представлений.
Часто требуется щелкнуть на представлении и проверить
некоторое условие относительно результата щелчка. Также
можно воспользоваться Espresso для моделирования щелчков
на представлениях или других взаимодействий с ними:
onView(withText("65_cjipie"))
.perform(click())
Когда вы взаимодействуете с представлением, Espresso
дождется бездействия приложения, перед тем как продолжать
тестирование. В Espresso существуют встроенные средства
проверки
завершения
обновлений
пользовательского
интерфейса, но если вам потребуется более продолжительное
ожидание — используйте подкласс
IdlingResource
для
передачи Espresso сигнала о том, что приложение еще не
завершило свои операции.
За дополнительной информацией о том, как использовать
Espresso для манипуляций с пользовательским интерфейсом и
его тестирования, обращайтесь к документации Espresso по
адресу
Do'stlaringiz bilan baham: |