Как создать тесты в Android Studio?
Только что загрузили Android Studio, основанную на Intellij Idea.
Как создать тесты?
Я заметил, что есть опция для создания тестового модуля, но это ничего не делает, только создает новый проект с помощью src
Я также попытался нажать горячую клавишу CTRL + AlT + T, которая позволяет создавать модульные тесты для существующего класса, но, кажется, он хочет поместить его в текущий проект. Конечно, это не помогает с TDD
У кого-нибудь есть опыт здесь?
Этот ответ предназначен для тех, кто только начинает тестирование Android. Я приведу два простых примера, которые помогут вам понять, как работает тестирование. Если вы будете следовать в течение следующих 10 минут, у вас будет все готово, чтобы начать добавлять свои тесты в собственное приложение. Я думаю, вы удивитесь, насколько это просто. Я конечно был.
Введение в Android Тестирование
Есть два разных типа тестов, которые вы будете делать.
- Локальные модульные тесты. Они выполняются локально на JVM (виртуальная машина Java). Так как они местные, они быстрые. Вы можете использовать их для тестирования частей вашего кода, которые просто нуждаются в Java, а не в Android API. (Иногда вы можете создать поддельный объект API для локального тестирования большего количества вещей. Это называется насмешливый . Примером Context является пример.)
- Инструментированные тесты. Эти тесты выполняются на реальном устройстве или в эмуляторе. Это делает их медленнее, чем местные тесты. Однако они более гибкие, поскольку у вас есть полный доступ к API Android.
Создайте новый проект, и вы увидите следующие папки по умолчанию.
Все уже есть и ждут, когда вы создадите свои тесты. Все уже настроено!
Как создать локальные юнит-тесты
Откройте файл ExampleUnitTest , показанный на изображении выше. это должно выглядеть примерно так:
Нажмите двойную зеленую стрелку, чтобы запустить все тесты, или одну зеленую стрелку, чтобы запустить только один. (В этом случае есть только один тест, поэтому они оба делают одно и то же.)
Это должно пройти (пока 2 + 2 все еще 4 , когда вы читаете этот ответ). Поздравляем, вы только что провели первый тест!
Создание собственного теста
Давайте напишем наш собственный тест. Сначала добавьте этот класс в основной проект приложения, чтобы у нас было что проверить:
Теперь измените метод addition_isCorrect() в тестовом классе так, чтобы он был похож на следующий код (или просто добавьте другой метод с другим именем):
Запустите его снова, и вы должны увидеть, как он прошел. Поздравляем, вы только что создали свой первый тест! (Ну, я думаю, технически это было мое, но, эй, достаточно близко. Что мое, то ваше.)
Как создавать инструментальные тесты
Откройте файл ExampleInstrumentedTest . это должно выглядеть примерно так:
Нажмите одну из этих зеленых кнопок еще раз.
Если у вас подключено реальное устройство или настроен эмулятор, он должен был запустить его и запустить ваше приложение. Поздравляем, вы только что провели первый инструментальный тест!
Создание собственного теста
Инструментированные тесты используют Espresso для запуска тестов. Это своего рода маленький пользователь-робот, который может протестировать ваше приложение. Вы можете сказать ему сделать что-то вроде нажатия кнопки или чтения свойств TextView.
Вы можете написать инструкции о том, как выполнить тест вручную, но так как мы только начинаем, давайте использовать функция автоматической записи . Это супер просто.
Сначала добавьте кнопку в свой интерфейс, чтобы у нас было с чем работать. Я сделал это:
Затем нажмите Run> Record Espresso Test в меню.
После того, как он запустится, нажмите кнопку в эмуляторе, а затем, чтобы закончить, выберите OK в диалоговом окне записи. Он должен автоматически сгенерировать следующий тестовый код.
Большой! Вы только что создали первый инструментальный тест! Это было супер легко. Вы, вероятно, должны добавить утверждение, чтобы сделать его настоящим тестом, но это также довольно легко сделать с рекордером. Смотрите это видео , чтобы пойти немного глубже.
Дальнейшее обучение
Сначала я смотрел видео, а потом читал документацию. Это все очень полезно. Последняя ссылка — на серию статей, в которых рассматриваются некоторые важные вещи, которые следует учитывать при выборе того, что тестировать.
Правка: Начиная с .1.8 теперь поддерживается в IDE . Пожалуйста, следуйте инструкциям там, вместо того, чтобы использовать инструкции ниже.
Следуя Руководство пользователя плагина Android Gradle Я смог получить тесты, работающие в командной строке, выполнив следующие шаги для вновь созданного проекта (я использовал стандартный пакет ‘com.example.myapplication’):
- Добавить каталог src/instrumentTest/Java для тестов
- Добавьте тестовый класс (расширяющий ActivityTestCase) в пакет com.example.myapplication.test
- Запустите виртуальное устройство
- В командной строке (в каталоге MyApplicationProject/MyApplication) используйте команду ‘../gradlew connectedInstrumentTest’
Это запустило мои тесты и поместило результаты теста в MyApplicationProject/MyApplication/build/reports/instrumentTests/connected. Я новичок в тестировании Android приложений, но, похоже, работает нормально.
Из среды IDE можно попробовать запустить тот же тестовый класс. Вам нужно будет
- Обновите build.gradle, чтобы указать Maven Central в качестве репозитория
- Обновите build.gradle, добавьте JUnit 3.8 в качестве зависимости toolTestCompile, например, toolTestCompile ‘junit: junit: 3.8’
- В «Структуре проекта» вручную переместите JUnit, чтобы быть первым в порядке зависимости
Однако это терпит неудачу (путь к классу, используемый при выполнении тестов, отсутствует в каталоге выходных данных теста). Однако я не уверен, что это сработает, независимо от того, насколько я понимаю, что требуется специальный тестировщик Android.
Я бы предложил использовать файл gradle.build.
Добавьте каталог src/androidTest/Java для тестов (Как Крис начинает объяснять)
Откройте файл gradle.build и укажите там:
Нажмите «Синхронизировать проект с файлом Gradle» (на верхней панели). Теперь вы должны увидеть папку «Java» (внутри «androidTest») зеленого цвета.
Теперь вы можете создавать там любые тестовые файлы и выполнять их.
Я думаю этот пост от Rex St John очень полезен для модульного тестирования в студии Android.
Android Studio v.2.3.3
Выделите контекст кода, который вы хотите протестировать, и используйте горячую клавишу: CTRL + SHIFT + T
Используйте диалоговый интерфейс, чтобы завершить настройку.
Предполагается, что инфраструктура тестирования будет отражать макет пакета вашего проекта для достижения наилучших результатов, но вы можете вручную создавать собственные тесты, если у вас есть правильные каталог и настройки сборки.
На данный момент (студия 0.61) достаточно поддерживать правильную структуру проекта. Нет необходимости создавать отдельный тестовый проект, как в Eclipse (см. Ниже).
Android Studio продолжает развиваться, поэтому приведенные выше ответы в конечном итоге перестанут применяться. Для текущей версии Android Studio 1.2.1.1 есть хорошее руководство по тестированию:
Похоже, одно из основных изменений заключается в том, что в Android Studio тестовое приложение интегрировано в проект приложения.
Я не уверен, поможет ли это вашей конкретной проблеме, но я нашел руководство по созданию тестов с проектом Gradle. Руководство пользователя Android Gradle
Самый простой способ, который я нашел, — это упорядоченный в мой следующий пост в блоге :
- Создайте папку, в которую вы будете писать все свои юнит-тесты (предпочтительно com.example.app.tests)
- Создайте новый тестовый класс (предпочтительно NameOfClassTestedTests, т.е. BankAccountLoginActivityTests)
- Расширить InstrumentationTestCase
- Напишите провальный модульный тест, чтобы убедиться, что мы успешно настроили модульные тесты
- Обратите внимание, что имя метода модульного теста должно начинаться со слова «test» (предпочтительно testTestedMethodNameExpectedResult (), т.е. testBankAccountValidationFailedShouldLogout ())
- Сконфигурируйте ваш проект для модульных тестов:
- Откройте меню «Выполнить . » и нажмите «Изменить настройки»
- Нажмите кнопку +
- Выберите шаблон Android Тесты
- Введите имя для своей конфигурации запуска (предпочтительно «Тесты AppName»)
- Выберите ваше приложение в модуле выпадающего списка
- Выберите переключатель «Все в пакете» (обычно вы хотите выбрать этот параметр, поскольку он запускает все модульные тесты во всех ваших тестовых классах).
- Введите имя тестового пакета, начиная с шага 1 (например, com.example.app.tests).
- Выберите устройство, на котором вы хотите запустить свои тесты
- Применить и сохранить конфигурацию
- Запустите юнит-тесты (и ожидайте сбой):
- Выберите вновь созданную конфигурацию тестов в меню «Выполнить»
- Нажмите Run и прочитайте результаты в консоли вывода.
Удачи в том, чтобы сделать ваш код более читабельным, поддерживаемым и хорошо протестированным!
Android Studio была своего рода движущейся целью: сначала она представляла собой предварительную версию для разработчиков, а сейчас находится в бета-версии. Путь к классам Test в проекте менялся с течением времени, но независимо от того, какую версию AS вы используете, путь объявляется в вашем файле .iml. В настоящее время с версией 0.8.3 вы найдете следующее во внутреннем IML-файле:
Файл .iml сообщает вам, где разместить тестовые классы.
Начиная с Android Studio 1.1, у нас есть официальная (экспериментальная) поддержка написания модульных тестов (Roboelectric работает также).
Добавьте ниже lib внутри файла gradle
Создайте класс HomeActivityTest в каталоге androidTest и перед запуском теста добавьте строку flurry_api_key и sender_id в строковый файл ресурсов и измените значение для случая неудачи и успеха.
Источник
А/В-тесты на Android от А до Я
Большая часть статей об A/B-тестах посвящена веб-разработке, и несмотря на актуальность этого инструмента и для других платформ, мобильная разработка несправедливо остаётся в стороне. Мы попытаемся эту несправедливость устранить, описав основные шаги и раскрыв особенности реализации и проведения A/B-тестов на мобильных платформах.
Концепция A/B-тестирования
A/B-тест нужен для проверки гипотез, направленных на улучшение ключевых метрик приложения. В простейшем случае пользователи делятся на 2 группы контрольную (A) и экспериментальную (B). Фича, реализующая гипотезу, раскатывается только на экспериментальную группу. Далее на основе сравнительного анализа показателей метрики для каждой из групп делается вывод о релевантности фичи.
Реализация
1. Делим пользователей на группы
Для начала нам необходимо понять, как мы будем делить пользователей на группы в нужном процентном соотношении с возможностью динамически его менять. Такая возможность будет особенно полезна, если вдруг выяснится, что новая фича повышает конверсию на 146%, а раскатана, например, всего на 5% пользователей! Наверняка нам захочется выкатить её на всех пользователей и прямо сейчас — без обновления приложений в сторе и сопутствующих временных издержек.
Конечно, можно организовать разбивку на сервере и каждый раз при необходимости что-то менять дёргать backend-разработчиков. Но в реальной жизни бэк зачастую разрабатывается на стороне заказчика или третьей компанией, и у серверных разработчиков и так хватает дел, поэтому оперативно регулировать разбивку, работая с третьими лицами, удаётся не всегда, а точнее, почти никогда, поэтому такой вариант нам не подходит. И тут на помощь приходит Firebase Remote Config!
В Firebase Console, в группе Grow есть вкладка Remote Config, где вы можете создать свой конфиг, который Firebase доставит пользователям вашего приложения.
Конфиг представляет собой мапу с возможностью присваивать значение параметра по условию. Например, пользователям с конкретной версией приложения значение X, всем остальным — Y. Более подробно о конфиге можно узнать в соответствующем разделе документации.
Также в группе Grow есть вкладка A/B Testing. Здесь мы можем запускать тесты со всеми вышеописанными плюшками. В качестве параметров используются ключи из нашего Remote Config. В теории можно прямо в A/B-тесте создать новые параметры, но это только внесёт лишнюю путаницу, поэтому делать так не стоит, проще добавить соответствующий параметр в конфиг. Значение в нем традиционно является значением по умолчанию и соответствует контрольной группе, а экспериментальное значение параметра, отличное от дефолтного — экспериментальной.
Прим. Контрольная группа обычно называется группой A, экспериментальная — группой B. Как видно на скрине, в Firebase по умолчанию экспериментальная группа называется “Variant A”, что вносит некоторую путаницу. Но ничто не мешает изменить её название.
Далее запускаем A/B-тест, Firebase разбивает пользователей на группы, которым соответствуют разные значения параметра, получив конфиг на клиенте, мы достаём из него нужный параметр и на основе значения применяем новую фичу. Традиционно параметр имеет имя соответствующее названию фичи, и 2 значения: True — фича применяется, False — не применяется. Подробнее о настройках A/B-тестов в соответствующем разделе документации.
2. Кодим
Не будем останавливаться непосредственно на интеграции с Firebase Remote Config — она подробно описана здесь.
Разберём способ организации кода для проведения A/B-тестирования. Если мы просто меняем цвет кнопки, то говорить об организации нет смысла, ибо организовывать особенно нечего. Мы рассмотрим вариант, в котором в зависимости от параметра из Remote Config показывается текущий (для контрольной группы) или новый (для экспериментальной) экран.
Нужно понимать, что по истечению A/B-теста один из вариантов экрана надо будет удалить, в связи с этим организовать код необходимо таким образом, чтобы минимизировать изменения в текущей реализации. Все файлы связанные с новым экраном стоит называть с префиксом AB и помещать в папки с таким же префиксом.
Если мы говорим об MVP в Presentation слое, выглядеть это будет примерно так:
Наиболее гибкой и прозрачной представляется следующая иерархия классов:
BaseOrderStatusFragment будет содержать весь функционал текущей реализации, кроме методов, которые не могут быть размещены в абстрактном классе из-за ограничений архитектуры. Они будут располагаться в OrderStatusFragment.
AbOrderStatusFragment будет переопределять методы, различающиеся в реализации, и иметь необходимые дополнительные. Таким образом, в текущей реализации изменится лишь разбивка одного класса на два и некоторые методы в базовом классе станут protected open вместо private.
Примечание: если архитектура и конкретный кейс позволяют, можно обойтись без создания базового класса и напрямую наследовать AbOrderStatusFragment от OrderStatusFragment.
В рамках такой организации скорее всего придётся отступить от принятого CodeStyle, что в данном случае допустимо, ибо соответствующий код будет удалён или отрефакторен по завершению A/B-теста (но, конечно, в местах нарушения CodeStyle стоит оставить коммент)
Подобная организация позволит нам быстро и безболезненно удалить новую фичу, если она окажется нерелевантной, поскольку все связанные с ней файлы легко найти по префиксу и её реализация не влияет на текущий функционал. В случае же, если фича улучшила ключевую метрику и принято решение оставить её, нам всё равно предстоит работа по выпиливанию текущего функционала, что повлияет на код новой фичи.
Для получения конфига стоит создать отдельный репозиторий и заинжектить его на уровень приложения, чтобы он был везде доступен, так как мы не знаем, какие части приложения затронут будущие A/B-тесты. По этим же причинам запрашивать его стоит как можно раньше, например, вместе с основной информацией, необходимой для работы приложения (обычно такие запросы происходят во время показа сплеша, хотя это холиварная тема, но важно что где-то они есть).
Ну, и, естественно, важно не забыть прокинуть значение параметра из конфига в параметры событий аналитики, чтобы была возможность сравнить метрики
Анализ результатов
Есть немало статей, подробно рассказывающих про способы анализа результатов A/B-тестов, например. Чтобы не повторяться, просто укажем суть. Нужно понимать, что разница метрик на контрольной и экспериментальной группе — случайная величина, и мы не можем сделать вывод о релевантности фичи только на основе того, что на экспериментальной группе показатель метрики лучше. Необходимо построить доверительный интервал (выбор уровня надёжности стоит доверить аналитикам) для вышеописанной случайной величины и проводить эксперимент до тех пор, пока интервал полностью не окажется в положительной или отрицательной полуплоскости — тогда можно будет сделать статистически достоверный вывод.
Подводные камни
1. Ошибка при получении Remote Config
Сравнительный анализ проводится на новых пользователях, так как в экспериментах должны участвовать юзеры с одинаковым пользовательским опытом и только те, кто видел единственный вариант реализации. Напомним, что получение конфига является сетевым запросом и может закончится неудачей, в таком случае будет применено значение по умолчанию, традиционно равное значению для контрольной группы.
Рассмотрим следующий кейс: у нас есть пользователь, которого Firebase отнёс к экспериментальной группе. Пользователь первый раз запускает приложение и запрос Remote Config возвращает ошибку — пользователь видит старый экран. При следующем запуске запрос Remote Config отрабатывает корректно и пользователь видит новый экран. Важно понимать, что такой пользователь не является релевантным для эксперимента, поэтому нужно придумать, как отсеивать такого пользователя на стороне системы аналитики, либо доказать, что число таких пользователей пренебрежимо мало.
На самом деле такие ошибки действительно возникают нечасто, и скорее всего вам подойдёт последний вариант, но есть по сути аналогичная, но куда более насущная проблема — время получения конфига. Как было сказано выше, лучше засунуть запрос Remote Config в начало сессии, но если запрос будет идти слишком долго, пользователю надоест ждать, и он выйдет из приложения. Поэтому нужно решить нетривиальную задачу — выбрать тайм-аут, по которому сбрасывается запрос Remote Config. Если он будет слишком мал, то большой процент пользователей может оказаться в списке нерелевантных для теста, если слишком большим — мы рискуем вызвать гнев пользователей. Мы собрали статистику по времени получения конфига:
Примечание. Данные за последние 30 дней. Общее кол-во запросов 673 529. Первый столбец, помимо сетевых запросов, содержит получения конфига из кеша, поэтому выбивается из общей формы распределения.
Источник