Country not specified
Unknown website Share

Apps4all

Страна: -
Город: -
Был онлайн: -
О себе:
 
08-07-2016, 11:04
Apps4all

​Автоматическое тестирование Android с UiAutomator

Я хочу рассказать вам о замечательном инструменте для автоматического тестирования пользовательского интерфейса в приложениях Android - UiAutomator. Вы можете найти всю актуальную документацию здесь: http://developer.android.com/tools/help/uiautomator/index.html и http://developer.android.com/tools/testing/testing_ui.html

У UiAutomator есть свои плюсы и минусы.

Преимущества:

  • Он может быть использован на дисплеях устройств с различным разрешением.
  • События можно привязывать к элементам управления AndroidUI. К примеру, кликайте на кнопку с текстом «Ок» вместо того, чтобы кликать по расположению координат (x=450, y=550).
  • Инструмент может воспроизводить сложную последовательность действий пользователя.
  • Он всегда выполняет одну и ту же последовательность действий, позволяя нам собирать данные о производительности на разных устройствах.
  • Он может многократно выполняться на различных устройствах без изменения Java-кода.
  • Может использовать аппаратные кнопки на устройствах.

Недостатки:

  • Его сложно использовать с OpenGL- и HTML5-приложениями, поскольку они не имеют компонентов AndroidUI.
  • Время, затрачиваемое на написание JavaScript.

Разработка скрипта

Чтобы познакомить вас с работой UiAutomator, я хочу продемонстрировать простую программу. Это стандартное Android-приложение для месседжинга, которое может отсылать SMS-сообщения на любой телефонный номер.

Вот короткое описание действий, которые мы осуществили:

  • 1. Найти и запустить приложение
  • 2. Создать и отправить SMS-сообщения

Как видите, это очень просто.

Подготовка к тесту

Для анализа интерфейса будем использовать uiautomatorviewer.

54870da7d15ee0.50716941.png

Uiautomatorviewer показывает разделенный скриншот всех компонентов UI в Node Detail, чтобы вы могли видеть их разнообразные свойства. Там же в свойствах вы можете найти искомый элемент.

Настройка среды разработки

Если вы используете Eclipse:

  • 1.Создайте новый Java-проект в Eclipse. Мы назовем наш проект: SendMessage.
  • 2.Клик правой кнопкой на вашем проекте в Project Explorer и затем клик на Properties.
  • 3.В Properties выберите Java Build Path и добавьте требуемые библиотеки:
  • Кликните Add Library > JUnit и там выберите JUnit3, чтобы добавить поддержку для JUnit
  • Кликните Add External JARs ...
  • В <android-sdk>/platforms/directory выберитепоследнююверсию SDK. Также в этой директории выберите файлы uiautomator.jar и android.jar

Если вы пользуетесь иной средой разработки, убедитесь что файлы android.jar и uiautomator.jar добавлены в настройки проекта.

Создание скрипта

Создайте проект в ранее созданном новом файле с классом Java. Назовите его SendMessage. Этот класс унаследован из класса UiAutomatorTestCase. Используя Ctrl + Shift + o (для Eclipse), добавьте требуемые библиотеки.

Создайте три функции для тестирования этого приложения:

  • Найти и запустить приложение
  • Отправить SMS-сообщения
  • Выйти в главное меню приложения

Создайте функцию, от которой будут запускаться все эти опции, – своего рода основную функцию:

1 public void test() { 

2 // Here will be called for all other functions 

3 }

Функция поиска и запуска приложения

Эта функция крайне проста. Мы нажимаем кнопку Домой, открываем меню и ищем значок приложения. Нажимаем и запускаем его.

01 private void findAndRunApp() throws UiObjectNotFoundException {
02 // Go to main screen
03 getUiDevice().pressHome();
04 // Find menu button
05 UiObject allAppsButton = new UiObject(new UiSelector()
06 .description("Apps"));
07 // Click on menu button and wait new window
08 allAppsButton.clickAndWaitForNewWindow();
09 // Find App tab
10 UiObject appsTab = new UiObject(new UiSelector()
11 .text("Apps"));
12 // Click on app tab
13 appsTab.click();
14 // Find scroll object (menu scroll)
15 UiScrollable appViews = new UiScrollable(new UiSelector()
16 .scrollable(true));
17 // Set the swiping mode to horizontal (the default is vertical)
18 appViews.setAsHorizontalList();
19 // Find Messaging application
20 UiObject settingsApp = appViews.getChildByText(new UiSelector()
21 .className("android.widget.TextView"), "Messaging");
22 // Open Messaging application
23 settingsApp.clickAndWaitForNewWindow();
24
25 // Validate that the package name is the expected one
26 UiObject settingsValidation = new UiObject(new UiSelector()
27 .packageName("com.android.mms"));
28 assertTrue("Unable to detect Messaging",
29 settingsValidation.exists());
30 }

Все наименования классов, текст на кнопках и пр. - из uiautomatorviewer.

Посылка SMS-сообщения

Эта функция находит и нажимает кнопку создания нового сообщения, вводит телефонный номер адресата и нажимает кнопку отправки. Телефонный номер и текст проходят через параметры функции:

01 private void sendMessage(String toNumber, String text) throws UiObjectNotFoundException {
02 // Find and click New message button
03 UiObject newMessageButton = new UiObject(new UiSelector()
04 .className("android.widget.TextView").description("New message"));
05 newMessageButton.clickAndWaitForNewWindow();
06
07 // Find to box and enter the number into it
08 UiObject toBox = new UiObject(new UiSelector()
09 .className("android.widget.MultiAutoCompleteTextView").instance(0));
10 toBox.setText(toNumber);
11 // Find text box and enter the message into it
12 UiObject textBox = new UiObject(new UiSelector()
13 .className("android.widget.EditText").instance(0));
14 textBox.setText(text);
15
16 // Find send button and send message
17 UiObject sendButton = new UiObject(new UiSelector()
18 .className("android.widget.ImageButton").description("Send"));
19 sendButton.click();
20 }

Отображаемые поля для телефонного номера и текстового сообщения не имеют никаких специальных свойств: ни текста, ни какого-то иного описания для этих полей не предусмотрено. Поэтому в данном случае я могу найти их, используя элемент под его порядковым номером в иерархии интерфейса. Чтобы добавить возможность передавать параметры в скрипт, мы можем точно определить число адресатов и сами сообщения. Функция test() устанавливает параметры по умолчанию, и если какими-либо из параметров были отправленные через командную строку сообщения, заменой параметрам по умолчанию были бы:

01 // Default parameters
02 String toNumber = "123456";
03 String text = "Test message";
04
05 String toParam = getParams().getString("to");
06 String textParam = getParams().getString("text");
07 if (toParam != null) {
08 // Remove spaces
09 toNumber = toParam.trim();
10 }
11 if (textParam != null) {
12 text = textParam.trim();
13 }

Таким образом, мы сможем передавать параметры из командной строки скрипта, используя ключ –e, имя параметра и значение. К примеру, мое приложение отсылает номер для отправки " 777777 »:-e to 777777 Есть и некоторые подвохи. К примеру, данное приложение не понимает некоторые символы, и происходит сбой. Вот некоторые из этих символов: space, &, <, > , (,) , ", ' , а также некоторые символы Unicode. При внедрении в скрипт я заменил эти символы текстовой строкой, например пробел : blogspaceblog. Получается, когда скрипт запускает UiAutomator, мы используем скрипт, который будет обрабатывать наши входные параметры. Мы добавляем в функцию test(), проверку наличия опций, парсим параметры и заменяем их реальными символами. Ниже представлен образец кода, наглядно демонстрирующий всё, что мы ввели ранее:

01 if (toParam != null) {
02 toParam = toParam.replace("blogspaceblog", " ");
03 toParam = toParam.replace("blogamperblog", "&");
04 toParam = toParam.replace("bloglessblog", "<");
05 toParam = toParam.replace("blogmoreblog", ">");
06 toParam = toParam.replace("blogopenbktblog", "(");
07 toParam = toParam.replace("blogclosebktblog", ")");
08 toParam = toParam.replace("blogonequoteblog", "'");
09 toParam = toParam.replace("blogtwicequoteblog", """);
10 toNumber = toParam.trim();
11 }
12 if (textParam != null) {
13 textParam = textParam.replace("blogspaceblog", " ");
14 textParam = textParam.replace("blogamperblog", "&");
15 textParam = textParam.replace("bloglessblog", "<");
16 textParam = textParam.replace("blogmoreblog", ">");
17 textParam = textParam.replace("blogopenbktblog", "(");
18 textParam = textParam.replace("blogclosebktblog", ")");
19 textParam = textParam.replace("blogonequoteblog", "'");
20 textParam = textParam.replace("blogtwicequoteblog", """);
21 text = textParam.trim();
22 }

Выход в главное меню приложения

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

01 private void exitToMainWindow() {
02 // Find New message button
03 UiObject newMessageButton = new UiObject(new UiSelector()
04 .className("android.widget.TextView").description("New message"));
05
06 // Press back button while new message button doesn't exist
07 while(!newMessageButton.exists()) {
08 getUiDevice().pressBack();
09 }
10 }

Исходный код

Вот и наш код:

001 package blog.send.message;
002 import com.android.uiautomator.core.UiObject;
003 import com.android.uiautomator.core.UiObjectNotFoundException;
004 import com.android.uiautomator.core.UiScrollable;
005 import com.android.uiautomator.core.UiSelector;
006 import com.android.uiautomator.testrunner.UiAutomatorTestCase;
007
008 public class SendMessage extends UiAutomatorTestCase {
009 public void test() throws UiObjectNotFoundException {
010 // Default parameters
011 String toNumber = "123456";
012 String text = "Test message";
013
014 String toParam = getParams().getString("to");
015 String textParam = getParams().getString("text");
016 if (toParam != null) {
017 toParam = toParam.replace("blogspaceblog", " ");
018 toParam = toParam.replace("blogamperblog", "&");
019 toParam = toParam.replace("bloglessblog", "<");
020 toParam = toParam.replace("blogmoreblog", ">");
021 toParam = toParam.replace("blogopenbktblog", "(");
022 toParam = toParam.replace("blogclosebktblog", ")");
023 toParam = toParam.replace("blogonequoteblog", "'");
024 toParam = toParam.replace("blogtwicequoteblog", """);
025 toNumber = toParam.trim();
026 }
027 if (textParam != null) {
028 textParam = textParam.replace("blogspaceblog", " ");
029 textParam = textParam.replace("blogamperblog", "&");
030 textParam = textParam.replace("bloglessblog", "<");
031 textParam = textParam.replace("blogmoreblog", ">");
032 textParam = textParam.replace("blogopenbktblog", "(");
033 textParam = textParam.replace("blogclosebktblog", ")");
034 textParam = textParam.replace("blogonequoteblog", "'");
035 textParam = textParam.replace("blogtwicequoteblog", """);
036 text = textParam.trim();
037 }
038 findAndRunApp();
039 sendMessage(toNumber, text);
040 exitToMainWindow();
041 }
042 // Here will be called for all other functions
043 private void findAndRunApp() throws UiObjectNotFoundException {
044 // Go to main screen
045 getUiDevice().pressHome();
046 // Find menu button
047 UiObject allAppsButton = new UiObject(new UiSelector()
048 .description("Apps"));
049 // Click on menu button and wait new window
050 allAppsButton.clickAndWaitForNewWindow();
051 // Find App tab
052 UiObject appsTab = new UiObject(new UiSelector()
053 .text("Apps"));
054 // Click on app tab
055 appsTab.click();
056 // Find scroll object (menu scroll)
057 UiScrollable appViews = new UiScrollable(new UiSelector()
058 .scrollable(true));
059 // Set the swiping mode to horizontal (the default is vertical)
060 appViews.setAsHorizontalList();
061 // Find Messaging application
062 UiObject settingsApp = appViews.getChildByText(new UiSelector()
063 .className("android.widget.TextView"), "Messaging");
064 // Open Messaging application
065 settingsApp.clickAndWaitForNewWindow();
066
067 // Validate that the package name is the expected one
068 UiObject settingsValidation = new UiObject(new UiSelector()
069 .packageName("com.android.mms"));
070 assertTrue("Unable to detect Messaging",
071 settingsValidation.exists());
072 }
073
074 private void sendMessage(String toNumber, String text) throws UiObjectNotFoundException {
075 // Find and click New message button
076 UiObject newMessageButton = new UiObject(new UiSelector()
077 .className("android.widget.TextView").description("New message"));
078 newMessageButton.clickAndWaitForNewWindow();
079
080 // Find to box and enter the number into it
081 UiObject toBox = new UiObject(new UiSelector()
082 .className("android.widget.MultiAutoCompleteTextView").instance(0));
083 toBox.setText(toNumber);
084 // Find text box and enter the message into it
085 UiObject textBox = new UiObject(new UiSelector()
086 .className("android.widget.EditText").instance(0));
087 textBox.setText(text);
088
089 // Find send button and send message
090 UiObject sendButton = new UiObject(new UiSelector()
091 .className("android.widget.ImageButton").description("Send"));
092 sendButton.click();
093 }
094
095 private void exitToMainWindow() {
096 // Find New message button
097 UiObject newMessageButton = new UiObject(new UiSelector()
098 .className("android.widget.TextView").description("New message"));
099
100 // Press back button while new message button doesn't exist
101 while(!newMessageButton.exists()) {
102 getUiDevice().pressBack();
103 sleep(500);
104 }
105 }
106 }

Компиляция и выполнение тестирования UiAutomator

1. Чтобы сгенерировать файлы конфигурации для экспериментальной сборки, выполните следующую команду из командной строки:
<android-sdk>/tools/androidсоздать uitest-проект -n <name> -t <target-id> -p <path>
где <
name>- это имя проекта, который был создан для тестирования UiAutomator (в нашем случае: SendMessage), <target-id>- выбор устройства и AndroidAPILevel (вы можете получить перечень установленных устройств с помощью команды<android-sdk> / tools / androidlisttargets), и <path> это путь к директории, где содержится проект.

2. Вы должны экспортировать переменную среды ANDROID_HOME:

  • На Windows: установите ANDROID_HOME=<путь_к_вашему_sdk>
  • На UNIX: экспортируйте ANDROID_HOME=<путь_к_вашему_sdk>

3. Откройте директорию с файлом проекта build.xml, который был создан на этапе 1, и выполните команду: antbuild

4. Скопируйте скомпилированный файл JAR на устройство, используя adbpush: adbpush <путь_к_output_jar> /data/local/tmp/
В нашем случае это:
adbpush <project_dir>/bin/SendMessage.jar /data/local/tmp/

5. И выполните скрипт:

adb shell uiautomator runtest /data/local/tmp/SendMessage.jar –c blog.send.message.SendMessage


Об авторе

Егор Чураев ( egor.churaev@intel.com) – Стажер по программному обеспечению

 
Intel
разработчикам
разработка
0 0 0

Чтобы оставлять комментарии вам необходимо зарегистрироваться