Ответ 1
Обновление апрель 2015: инструменты сборки Gradle и Android Studio теперь официально поддерживают модульное тестирование и предотвращают возникновение ошибки в stroid (без реальной реализации) в android.jar. Так что да, можно запускать тесты на Java VM, когда заглушки соответствующим образом проверяются. Это начало, но все еще не сравнимо с Robolectric. Существует также третий вариант, прокрутите до конца этого ответа.
Теперь о Robolectric:
Плюсы: вот несколько моментов о том, как это оказалось полезным в модульном тестировании:
-
Вам не нужно запускать эмулятор, поэтому вы можете протестировать некоторые части проекта, не связанные с пользовательским интерфейсом, не требуя эмулятора или устройства. Это также относится к запуску тестов на серверах непрерывной интеграции/сборки, запускать эмуляторы не нужно.
-
В Android Studio вы можете быстро запустить один конкретный класс тестирования, когда вы работаете над реализацией, чтобы удовлетворить тестовые случаи. Вы можете отлаживать, как вы пишете код. Это огромный прирост производительности.
-
Может подделывать почти все связанные с Android вещи как теневые объекты, даже SQLite. Плюс каждый теневой объект предоставляет множество полезных функций, которые не предлагают их обычные аналоги для Android. С теневыми аналогами Android-объекта вы можете выполнять внутреннюю проверку или вызывать специальные методы.
-
Действительно светит при тестировании многопоточного кода, такого как
AsyncTask
,Loopers
Handlers
и т.д. Вы можете приостановить и перемотать вперед поток Loopers, даже основной поток. Отлично подходит для тестирования обратного вызова на основе обработчика. -
Формат JUnit 4 поддерживается. Android все еще держит JUnit 3 в прошлый раз, когда я проверял.
-
Может сочетаться с другими инструментами для тестирования, такими как Mockito, Espresso и т.д.
-
Поддерживает создание макета экземпляра Activity
Robolectric.buildActivity()
и управление им черезActivityController
. Манипулирование фрагментами/представлениями также работает на таких ложных экземплярах действий. -
В настоящее время предоставляются дополнительные модули, которые охватывают multi-dex, поддержку v4, сервисы воспроизведения, карты и http-клиента. Таким образом, теперь легко тестировать код с использованием этих библиотечных функций.
Минусы: Где я нашел это не так хорошо:
-
Robolectric отлично справляется с тестированием модулей, но не охватывает всех функций, которые может предложить реальное устройство или эмулятор. Например, датчики, GPS, Open-GL и т.д. И т.д.
-
При интеграции или тестировании пользовательского интерфейса вам понадобится эмулятор или реальное устройство, чтобы действия и службы могли взаимодействовать с полной средой Android (другими приложениями, такими как приложение камеры, чтобы получить изображение для вашего приложения), а не ограниченным. Здесь вам нужно будет использовать тестовую среду по умолчанию, так как она имеет функции для тестирования пользовательского интерфейса.
-
Загрузка JNI, похоже, не поддерживается. Поэтому код с нативной зависимостью не может быть протестирован.
-
На данный момент Robolectric имеет жесткую зависимость от работы карты Google Maps. И загрузит еще один android.jar от maven. Таким образом, для настройки проекта может потребоваться немного поработать. Обновление: начиная с версии v3, кажется, без всякой суеты вытягивает все зависимости через Gradle.
-
Новые инструменты Android поддерживают покрытие, генерацию отчетов и т.д., Но только при запуске теста на устройстве. Так что с Robolectric вам придется создавать дополнительные задачи Gradle (запустить Jaococ), чтобы сделать это за вас. Обновление: Gradle 2.9 + поставляется с плагином jacoco.
-
Поскольку инструменты сборки gradle и android быстро и быстро выпускают новые версии сборки, стабильные версии Robolectric иногда начинают испытывать проблемы с измененными инструментами сборки. Наиболее типичные проблемы: несовместимость версии SDK, не обнаружен манифест, несоответствие путей вывода сборки, не загружаются ресурсы, проблемы с конфигурацией сборки и т.д. Некоторые проблемы также связаны с ошибками в инструментах Android. Иногда вам может даже понадобиться написать собственный пользовательский тестовый прогон или применить обходные пути, пока следующая версия не исправит эти проблемы. Проверьте открытые проблемы и настройте тесты соответственно.
Еще одна альтернатива - просто издеваться над собой самостоятельно, без каких-либо рамок. Это "трудный путь", но самый настраиваемый. Это простой JUnit с JMockit:
@RunWith(JMockit.class)
public class OtherTest {
public void testHandlerCallback(@Mocked final FragmentTransaction transaction,
@Mocked final FragmentManager manager,
@Mocked final Activity activity,
@Mocked final LayoutInflater inflater,
@Mocked final ViewGroup parent) {
final List<Fragment> fragments = new ArrayList<>();
new Expectations() {{
activity.getFragmentManager(); result = manager;
manager.beginTransaction(); result = transaction;
transaction.add(withCapture(fragments), anyString);
transaction.commit(); result = new Delegate<Void>() {
public int commit() {
View v = fragments.get(0).onCreateView(inflater,parent,null);
Deencapsulation.invoke(v,"onMeasure",0,0);
return 0;
}
};
}};
}
}
Выше приведен грубый и встроенный пример. На самом деле вы можете создать надлежащие повторно используемые классы (скажем, FragmentTestHarness
), которые будут брать тестируемый компонент (например, Fragment
) и помещать его в полностью изолированную среду, подготавливая его к тестам.