Robotium. В наборе тестов на каждый следующий тест влияет предыдущий тест
У меня есть несколько тестов пользовательского интерфейса. Когда я запускаю один тест, все в порядке. Но если я запускаю партию из них (как часть сборки CI), тест не пройден, потому что тесты, которые запускаются вначале, изменяют состояние приложения, и на следующие тесты влияют эти изменения. (Так как приложение не убивается).
Я старался getActivity().finish()
в tearDown()
,
Пытался solo.finalize()
который делает то же самое на самом деле.
Есть ли способ иметь новое приложение в начале каждого теста? (Использование Robotium).
И есть ли способ программно убить приложение в конце теста?
я использую ActivityInstrumentationTestCase2
с роботом
7 ответов
Почему бы не добавить специальный способ "убить" приложение, в зависимости от того, какое приложение вы тестируете? Например, в зависимости от глубины активности вашего приложения, "нажмите 3 раза назад" или что-то подобное может быть достаточно хорошим.
Вы можете добавить это в tearDown
метод ваших тестов суперкласса, так что он запускается после каждого из ваших тестов.
Вы должны думать о своем Robotium
тесты не как обычные юнит-тесты (это не так!), а как пользовательские кейсы, приемочные тесты. Поэтому, если вы хотите закрыть приложение, сделайте в этих тестах именно то, что вы ожидаете от пользователя, чтобы закрыть приложение.
Не совсем уверен в характере вашего набора тестов, но у меня были проблемы с запуском нескольких тестов "с нуля" и зависанием во втором тесте. Моя проблема была связана с порожденными действиями и была решена путем запуска действия с FLAG_ACTIVITY_CLEAR_TOP - конечно, это очищает стек, но я думаю, что вы этого хотите?
Intent i = new Intent();
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
setActivityIntent(i);
solo = new Solo(getInstrumentation(), getActivity());
Причины проблемы:
- Нет Android API, чтобы получить список всех действий в стеке.
- Обходной путь для (1) - использовать ActivityMonitor для отслеживания каждого запускаемого действия.
Robotium использует обходной путь, но он устанавливает свой ActivityMonitor ПОСЛЕ того, как тестовый пример ActivityInstrumentationTestCase2 начинает свою деятельность, т.е.
Activity activity = getActivity(); Solo solo = new Solo(getInstrumentation(), activity);
Если тестируемая вами активность является переадресацией, то, скорее всего, она начинает действие назначения до того, как Solo зарегистрирует свой ActivityMonitor. Solo.finishOPenedActivities() опирается на список, который он собрал из своего ActivityMonitor.
Согласно ответу@Guillaume, я вызываю этот метод из контрольного примера или tearDown():
private void backOutToHome() {
boolean more = true;
while(more) {
try {
getInstrumentation().sendKeyDownUpSync(KeyEvent.KEYCODE_BACK);
} catch (SecurityException e) { // Done, at Home.
more = false;
}
}
}
Мое решение:
@Override
public void tearDown() throws Exception {
solo.finishOpenedActivities();
super.tearDown();
}
Если вы запускаете вашу сборку с помощью maven или ant (Robotium - это удобная оболочка для JUnit-Tests), есть опция для ветвления нового процесса для каждого класса тестирования или даже теста. Это обеспечивает чистую среду, но замедляет выполнение теста.
Лично я предпочитаю придерживаться ванильного Junit / TestNG и использовать макеты (с jMockit), чтобы обеспечить надлежащее взаимодействие между моим кодом и Android. Смотрите образец здесь: