Как вы тестируете приложение Android в нескольких действиях?

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

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

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

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

Ответ 1

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

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

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 видов деятельности и доволен тем, что подход работает, хотя, как я уже сказал, существует случайный вопрос времени, который я не совсем понял. Мне все еще интересно узнать о каких-либо других способах тестирования различных видов деятельности.

Ответ 2

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

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

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

Ответ 3

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

Ответ 4

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

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

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

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

Ответ 5

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

Ответ 6

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

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

Из Javadocs: "ActivityInstrumentationTestCase2 (String pkg, Class activityClass) Этот конструктор устарел. вместо этого используйте ActivityInstrumentationTestCase2 (класс)

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

Ответ 7

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

Ответ 8

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

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)); 

Ответ 9

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

Ответ 10

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

Ответ 11

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

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

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

Ответ 12

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

Ответ 13

Этот ответ основан на принятом ответе, но изменен, чтобы решить проблему времени, которая для меня стала последовательной после добавления около полудюжины тестов. @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;
}

Ответ 14

Попробуйте выполнить тестирование инструмента Monkey

Шаг 1:

откройте терминал студии Android (Tools- > open terminal)

Шаг 2:

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

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

Шаг 3:

добавьте эту команду обезьяны в терминал и нажмите enter.

см. волшебство в эмуляторе.

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