78

Мы строим комплексное приложение для Android, состоящее из множества экранов и рабочих процессов, распространенных во многих видах деятельности. Наши рабочие процессы похожи на то, что вы можете увидеть на банкоматной машине Банка, например, есть Activity для входа в этот переход в главное меню Activity, которое может перейти на другие действия, основанные на выборе пользователя.Как вы тестируете приложение Android в нескольких действиях?

Поскольку у нас так много рабочих процессов, нам нужно создать автоматизированные тесты, которые охватывают несколько видов деятельности, чтобы мы могли протестировать рабочий процесс из конца в конец. Например, используя пример ATM, мы хотели бы ввести действительный PIN-код, убедиться, что он отправляет нас в главное меню, выберете наличные деньги, убедитесь, что мы находимся на экране наличных денег и т. Д. И т. Д., И, в конечном итоге, вернуться в главное меню или выйти из системы.

Мы поиграли с тестовым API, которые поставляются с Android (например, ActivityInstrumentationTestCase2), а также с Positron, но и не кажется, способно испытывать за пределами одного Activity, и в то время как мы можем найти применение в этих инструментах для некоторые единицы тестирования, они не будут соответствовать нашим требованиям для тестирования сценариев, которые пересекают несколько видов деятельности.

Мы открыты для рамки xUnit, скриптов, графических рекордеров/воспроизведения и т. Д. И будем благодарны за любые советы.

+2

На Android 4.1, в настоящее время новая система тестирования от Android, которая позволяет проводить тестирование а также всей системы: http://developer.android.com/tools/testing/testing_ui.html –

+1

[Robotium] (https://code.google.com/p/robotium/) удовлетворит эту потребность и только в нескольких строках. – Dori

ответ

64

Я чувствую себя немного неловко отвечая на мой собственный вопрос щедрости, но здесь ...

Я искал высоко и низко на этом и не могу поверить, что нет ответа опубликованы в любом месте. Я пришел очень близко. Я могу определенно запустить тесты, которые охватывают действия сейчас, но у моей реализации, похоже, есть некоторые проблемы с сроками, когда тесты не всегда проходят надежно. Это единственный пример, который я знаю об этих тестах в нескольких действиях. Надеюсь, мое извлечение и анонимность этого не привели к ошибкам. Это простейшее тест, где я ввожу имя пользователя и пароль в виде входа в систему деятельности, а затем наблюдать за надлежащее приветственное сообщение отображается на другой деятельности «Добро пожаловать»:

package com.mycompany; 

import android.app.*; 
import android.content.*; 
import android.test.*; 
import android.test.suitebuilder.annotation.*; 
import android.util.*; 
import android.view.*; 
import android.widget.*; 

import static org.hamcrest.core.Is.*; 
import static org.hamcrest.core.IsNull.*; 
import static org.hamcrest.core.IsInstanceOf.instanceOf; 
import static org.junit.Assert.*; 
import static com.mycompany.R.id.*; 

public class LoginTests extends InstrumentationTestCase { 

    @MediumTest 
    public void testAValidUserCanLogIn() { 

     Instrumentation instrumentation = getInstrumentation(); 

     // Register we are interested in the authentication activiry... 
     Instrumentation.ActivityMonitor monitor = instrumentation.addMonitor(AuthenticateActivity.class.getName(), null, false); 

     // Start the authentication activity as the first activity... 
     Intent intent = new Intent(Intent.ACTION_MAIN); 
     intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
     intent.setClassName(instrumentation.getTargetContext(), AuthenticateActivity.class.getName()); 
     instrumentation.startActivitySync(intent); 

     // Wait for it to start... 
     Activity currentActivity = getInstrumentation().waitForMonitorWithTimeout(monitor, 5); 
     assertThat(currentActivity, is(notNullValue())); 

     // Type into the username field... 
     View currentView = currentActivity.findViewById(username_field); 
     assertThat(currentView, is(notNullValue())); 
     assertThat(currentView, instanceOf(EditText.class)); 
     TouchUtils.clickView(this, currentView); 
     instrumentation.sendStringSync("MyUsername"); 

     // Type into the password field... 
     currentView = currentActivity.findViewById(password_field); 
     assertThat(currentView, is(notNullValue())); 
     assertThat(currentView, instanceOf(EditText.class)); 
     TouchUtils.clickView(this, currentView); 
     instrumentation.sendStringSync("MyPassword"); 

     // Register we are interested in the welcome activity... 
     // this has to be done before we do something that will send us to that 
     // activity... 
     instrumentation.removeMonitor(monitor); 
     monitor = instrumentation.addMonitor(WelcomeActivity.class.getName(), null, false); 

     // Click the login button... 
     currentView = currentActivity.findViewById(login_button; 
     assertThat(currentView, is(notNullValue())); 
     assertThat(currentView, instanceOf(Button.class)); 
     TouchUtils.clickView(this, currentView); 

     // Wait for the welcome page to start... 
     currentActivity = getInstrumentation().waitForMonitorWithTimeout(monitor, 5); 
     assertThat(currentActivity, is(notNullValue())); 

     // Make sure we are logged in... 
     currentView = currentActivity.findViewById(welcome_message); 
     assertThat(currentView, is(notNullValue())); 
     assertThat(currentView, instanceOf(TextView.class)); 
     assertThat(((TextView)currentView).getText().toString(), is("Welcome, MyUsername!")); 
    } 
} 

Этот код, очевидно, не очень читаемый. Я реально извлечь его в простую библиотеку с английского, как API, так что я могу просто сказать что-то вроде этого:

type("myUsername").intoThe(username_field); 
click(login_button); 

Я тестировал на глубину около 4 деятельности, и я удовлетворен тем, что подход работает, хотя как я уже сказал, по-видимому, есть случайный вопрос времени, который я не совсем понял. Мне все еще интересно узнать о других способах тестирования действий.

+3

Вы можете попробовать добавить аннотацию FlakyTest, чтобы повторить тест автоматически, когда проблемы с синхронизацией приводят к сбою. На самом деле это не решение, а жизнеспособное обходное решение в некоторых ситуациях. –

+0

Спасибо, что написали это! Я искал что-то с функциональностью ActivityMonitors для моего тестирования. Я просто не мог их найти. –

+0

Насколько я знаю, ничего, что вы сделали выше, не может быть выполнено с помощью 'ActivityInstrumentationTestCase2' – ericn

0

Я лично его не использовал, но ApplicationTestCase выглядит так, как будто это может быть то, что вы ищете.

+0

К сожалению, нет примеров, указывающих на то, что это так. – SingleShot

+0

Да, похоже, что ты прав ... был обманут именем. Я не могу понять этого. Лучший подход, который я получил до сих пор, - использовать ActivityUnitTestCase для позитронов, чтобы убедиться, что запущено следующее действие, но это не поможет вам построить согласованные истории. В качестве альтернативы, InstrumentationTestCase.launchActivity может позволить вам запустить любое количество действий, но я все еще пытаюсь выяснить материал Instrumentation. – Eric

0

Существует еще один способ сделать множественную деятельность с использованием ActivityInstrumentation Class .. Сво нормальный сценария автоматизации ... Во-первых получить фокус, что когда-либо объект, который вы хотите, а затем отправить ключ просто, как это образца кода

button.requestFocus(); 
sendKeys(KeyEvent.KEYCODE_ENTER); 

Единственное, что понимает каждый вызов API, поможет нам.

8

Вы всегда можете использовать Robotium. Он поддерживает тестирование Blackbox точно так же, как Selenium, но для Android. Вы найдете его в Robotium.орг

+1

Последний раз, когда я проверил, Robotium не может использоваться во всех видах деятельности. Это было исправлено сейчас? http://stackoverflow.com/questions/3840034/how-do-i-write-a-solo-robotium-testcase-that-uses-the-builtin-camera-to-take-a-pi – user77115

+3

Он всегда работали над действиями, пока они принадлежат к одному и тому же процессу. – Renas

21

Взгляните на Robotium
воляет тест с открытым исходным кодом, созданный, чтобы сделать автоматическое тестирование черного ящика в Android приложений значительно быстрее и проще, чем это возможно с Android испытаний приборов из-оф -Box.

Домашняя страница: http://www.robotium.org/
Источник: http://github.com/jayway/robotium

Пожалуйста, обратите внимание, что проект Robotium поддерживается компанией я работаю

+0

привет, Есть ли инструмент для записи? я проверил множество веб-сайтов и нашел testdroid, который записывает сценарии и запускает их. К сожалению, это не бесплатное программное обеспечение, знаете ли вы какое-либо бесплатное программное обеспечение, которое выполняет процесс записи? – thndrkiss

+0

@thndrkiss: Я не знаю ни одного такого инструмента. Если вы зададите вопросы на форуме Robotium, вы, скорее всего, получите лучший ответ. –

+2

Robotium - спасатель жизни. Это сделает ваш тест чрезвычайно простым для написания (вы в основном разговариваете с ним простым английским: нажмите на это, нажмите кнопку «Назад» и т. Д.). Вы можете протестировать что-либо, но вам не нужно знать крошечные детали. Он имеет как минимум два основных преимущества: вы можете тестировать приложения, в которых у вас нет исходного кода, и он полагается на пользовательский интерфейс, который делает его очень надежным (вы меняете свои контроллеры/модели намного больше, чем ваши взгляды ...) – tiktak

0

Будет принят подход работы с различными видами деятельности из различных приложений, подписанные разными сертификатами? Если нет, Robotium - лучший способ проверить действия в одном приложении.

3

Я создал инструмент для записи и воспроизведения для Android и сделал его доступным на GitHub. Он легко настраивается и используется, не требует программирования, работает с реальными устройствами (которые не должны быть внедрены) и автоматически сохраняет скриншоты при воспроизведении тестов.

+0

Это выглядит многообещающе. Для тех, кто не видит смысла: это кажется довольно хорошим решением для тестирования жестов (постукивание, перетаскивание и другие вещи) – tiktak

1

Я работаю на довольно много то же самое, и я, вероятно, пойти с вариацией на принятый ответ на этот вопрос, но я наткнулся Calculuon(gitHub) во время моих поисков решение.

3

Прежде всего, используйте «ActivityInstrumentationTestCase2», а не «InstrumentationTestCase», как ваш базовый класс. Я использую Robotium и регулярно тестирую несколько действий. Я обнаружил, что я должен указать активность входа как общий тип (и аргумент класса для конструктора).

Конструктор 'ActivityInstrumentationTestCase2' игнорирует аргумент пакета и не требует его. Конструктор, который принимает пакет, устарел.

От Javadocs: «ActivityInstrumentationTestCase2 (String упак, класс activityClass) Этот конструктор не рекомендуется использовать ActivityInstrumentationTestCase2 (класс) вместо»

Используя рекомендуемую базовый класс позволяет рамки для обработки определенного шаблонного, как начать вашей деятельности. Это делается по вызову 'getActivity()', если это необходимо.

3

Обнаружено, что это полезно с несколькими модификациями. Во-первых, getInstrumentation().waitForIdleSync() вылечит отслаивание. SingleShot говорит о , а также InstrumentationTestCase имеет функцию lauchActivity, которая может заменить начальные строки активности.

+0

спасибо, это хороший материал! – icecreamman

2

вы можете сделать это так, чтобы избежать чешуек времени ожидания рассинхронизации:

final Button btnLogin = (Button) getActivity().findViewById(R.id.button); 
Instrumentation instrumentation = getInstrumentation(); 

// Register we are interested in the authentication activity... 
Instrumentation.ActivityMonitor aMonitor = 
     instrumentation.addMonitor(mynextActivity.class.getName(), null, false); 

getInstrumentation().runOnMainSync(new Runnable() { 
     public void run() { 
      btnLogin.performClick(); 
     } 
    }); 

getInstrumentation().waitForIdleSync(); 

//check if we got at least one hit on the new activity 
assertTrue(getInstrumentation().checkMonitorHit(aMonitor, 1)); 
4

Я удивлен, что никто не упомянул некоторые из ведущих автоматизированных функционального тестирования инструментов. По сравнению с Robotium, они не требуют написания Java-кода.

MonkeyTalk: инструмент с открытым исходным кодом, поддерживаемый компанией Gorilla Logic.Плюсы: упрощает запись, а также язык сценариев более высокого уровня для нетехнических пользователей и является кросс-платформенным (включает iOS). Учитывая эти преимущества как требования, мы нашли, что это лучшее решение. Он также позволяет использовать customization, что можно сделать на их языке сценариев, используя Javascript.

Calabash-Android: инструмент с открытым исходным кодом для функций огурцов. Плюсы: записывайте функции в языке Gherkin, который является Business Readable, Domain Specific Language, который позволяет описывать поведение программного обеспечения без подробного описания того, как это поведение реализовано. Аналогичная, но не точная поддержка доступна для iOS в cucumber-ios. Возможности записи не так хороши, так как они создают двоичный вывод.

Несколько других ссылок:

  • Вот некоторые additional comparisons между Robotium, Monkeytalk и кальян. Он упоминает TestDroid как еще возможность.
  • В этом blog упоминается выше плюс NativeDriver и Bot-bot.
0

Этот ответ основан на принятом ответе, но изменен для решения проблемы времени, которая для меня стала последовательной после добавления около полудюжины тестов. @ pajato1 получает кредит за решение проблемы времени, как указано в принятых ответах.

/** 
* Creates a test Activity for a given fully qualified test class name. 
* 
* @param fullyQualifiedClassName The fully qualified name of test activity class. 
* 
* @return The test activity object or null if it could not be located. 
*/ 
protected AbstractTestActivity getTestActivity(final String fullyQualifiedClassName) { 
    AbstractTestActivity result = null; 

    // Register our interest in the given activity and start it. 
    Log.d(TAG, String.format("Running test (%s) with main class: %s.", getName(), fullyQualifiedClassName)); 
    instrumentation = getInstrumentation(); 

    Intent intent = new Intent(Intent.ACTION_MAIN); 
    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
    intent.setClassName(instrumentation.getTargetContext(), fullyQualifiedClassName); 
    // Wait for the activity to finish starting 
    Activity activity = instrumentation.startActivitySync(intent); 

    // Perform basic sanity checks. 
    assertTrue("The activity is null! Aborting.", activity != null); 
    String format = "The test activity is of the wrong type (%s)."; 
    assertTrue(String.format(format, activity.getClass().getName()), activity.getClass().getName().equals(fullyQualifiedClassName)); 
    result = (AbstractTestActivity) activity; 

    return result; 
} 
-2

Попробуйте Испытательной обезьяну инструмента

Шаг 1:

открыть андроид студийного терминала (Инструменты-> открытого терминала)

Шаг 2:

Для использования обезьяны , откройте командную строку и просто введите naviagte в следующий каталог.

export PATH=$PATH:/home/adt-bundle-linux-x86-20140702/sdk/platform-tools 

Шаг 3:

добавить эту команду обезьяну в купюроприемник и нажмите ввод ..

увидеть магию в вашем эмуляторе.

adb shell monkey -p com.example.yourpackage -v 500 

500- это количество частот или количество событий, которые необходимо отправить для тестирования.

вы можете изменить этот счет ..

Больше ссылки,

http://www.tutorialspoint.com/android/android_testing.htm

http://androidtesting.blogspot.in/2012/04/android-testing-with-monkey-tool.html

+0

Downvoters должны указать причину downvoting ... это рабочий код .. и официальный метод тестирования тоже. Если я ошибаюсь, я готов исправить свой ответ. –

Смежные вопросы