Ten dokument zawiera informacje referencyjne dotyczące skryptów Robo, w tym strukturę, możliwości, użycie, nagrywanie i działania. Skrypty Robo to testy, które automatyzują ręczne zadania zapewniania jakości (QA) dla aplikacji mobilnych i umożliwiają ciągłą integrację (CI) oraz strategie testowania przed uruchomieniem. Skrypt Robo to plik JSON opisujący sekwencję interfejsu użytkownika (UI) i innych działań.
Możesz utworzyć skrypt Robo na następujące sposoby:
- Użyj funkcji nagrywania skryptów Robo.
- Utwórz ręcznie skrypt Robo.
- Nagraj skrypt Robo, a następnie edytuj go ręcznie.
Aby dowiedzieć się więcej o używaniu skryptów Robo, zobacz Uruchamianie skryptu Robo .
Skrypt Robo jest dostarczany do Robo test wraz z innymi danymi wejściowymi, takimi jak testowany pakiet aplikacji na Androida (APK).
Poniżej znajduje się przykład skryptu Robo, który podpisuje użytkownika w aplikacji, co jest uruchamiane po uruchomieniu testowanej aplikacji:
[
{
"crawlStage": "crawl",
"contextDescriptor": {
"condition": "app_under_test_shown"
},
"actions": [
{
"eventType": "VIEW_TEXT_CHANGED",
"replacementText": "user123",
"elementDescriptors": [
{
"resourceId": "my.app.package:id/username"
}
]
},
{
"eventType": "VIEW_TEXT_CHANGED",
"replacementText": "12345",
"elementDescriptors": [
{
"resourceId": "my.app.package:id/password"
}
]
},
{
"eventType": "VIEW_CLICKED",
"elementDescriptors": [
{
"resourceId": "my.app.package:id/login"
}
]
}
]
}
]
Jeśli w pliku znajduje się pojedynczy skrypt Robo i ma on domyślny warunek wyzwalający app_under_test_shown
, jak w powyższym przykładzie, możesz określić skrypt Robo w pliku przy użyciu prostszego formatu - tak jak sekwencję jego działań:
[
{
"eventType": "VIEW_TEXT_CHANGED",
"replacementText": "user123",
"elementDescriptors": [
{
"resourceId": "my.app.package:id/username"
}
]
},
{
"eventType": "VIEW_TEXT_CHANGED",
"replacementText": "12345",
"elementDescriptors": [
{
"resourceId": "my.app.package:id/password"
}
]
},
{
"eventType": "VIEW_CLICKED",
"elementDescriptors": [
{
"resourceId": "my.app.package:id/login"
}
]
}
]
Struktura
Skrypt Robo ma kilka atrybutów opisujących sposób, w jaki Robo go wykonuje. Większość z tych atrybutów jest opcjonalna z predefiniowanymi wartościami domyślnymi:
Atrybut | Opis |
id | Liczba całkowita, która pomaga śledzić ten skrypt Robo w wynikach indeksowania. |
description | Podobny do id , ale bardziej opisowy. |
crawlStage | Etap przeszukiwania Robo stosuje ten skrypt Robo w. Domyślnie jest to główny etap indeksowania. |
priority | Priorytet tego skryptu Robo w porównaniu do innych skryptów Robo. Domyślnie wszystkie skrypty Robo mają priorytet 1 . |
maxNumberOfRuns | Określa, ile razy podczas przeszukiwania Robo może wykonać ten skrypt Robo. Domyślnie Robo może jednorazowo wykonać skrypt Robo. |
contextDescriptor | Opisuje kontekst/warunek, który wyzwala ten skrypt Robo. Jeśli zostanie pominięty, warunek aktywacji tego skryptu Robo jest uważany za zawsze spełniony; innymi słowy, skrypt Robo jest bezwarunkowy. |
actions | Wszystkie działania tego skryptu Robo. |
Pojedynczy plik zawiera zbiór jednego lub więcej skryptów Robo.
Poniżej znajduje się przykład pliku z dwoma bezwarunkowymi skryptami Robo, z których każdy zawiera pojedynczą akcję wykonywaną raz na początku przeszukiwania:
[
{
"id": 1000,
"description": "My first Robo script",
"actions": [
{
"eventType": "DISABLE_KEYBOARD"
}
]
},
{
"id": 1001,
"description": "My second Robo script",
"actions": [
{
"eventType": "PRESSED_BACK"
}
]
}
]
Deskryptor kontekstu
Deskryptor kontekstu definiuje kontekst/warunek, który wyzwala skrypt Robo, używając jednego lub kombinacji kilku atrybutów:
Atrybut | Opis |
---|---|
"condition": "element_present" | Sprawdza, czy na ekranie znajduje się widżet interfejsu użytkownika, który pasuje do elementDescriptors lub tekstu określonego przez visionText . |
"condition": "element_disabled" | Sprawdza, czy widżet interfejsu użytkownika pasujący do elementDescriptors jest obecny na ekranie i nie można z nim wchodzić w interakcje. |
"condition": "element_checked" | Sprawdza, czy na ekranie znajduje się widżet interfejsu użytkownika pasujący do elementDescriptors i czy jest on sprawdzany. |
"condition": "app_under_test_shown" | Sprawdza, czy testowana aplikacja działa na pierwszym planie. |
"condition": "default_launcher_shown" | Sprawdza, czy wyświetlany jest ekran główny urządzenia, co oznacza, że na pierwszym planie nie działają żadne aplikacje. |
"condition": "non_roboscript_action_performed" | Sprawdza, czy ostatnia akcja wykonana przez test Robo nie jest akcją skryptu Robo. |
negateCondition | Jeśli ustawiona na true , neguje condition . Możesz na przykład użyć tego atrybutu, aby sprawdzić, czy widżet interfejsu użytkownika NIE jest obecny na ekranie lub czy testowana aplikacja NIE działa na pierwszym planie. |
elementDescriptors | Jeden lub więcej deskryptorów elementów, które identyfikują widżet interfejsu użytkownika na ekranie. Jest używany w połączeniu z warunkami element_present , element_disabled i element_checked . Wzajemnie wykluczające się z visionText . Aby uzyskać więcej informacji, zobacz sekcję Deskryptory elementów . |
visionText | Tekst na ekranie jest wykrywany za pomocą interfejsu API optycznego rozpoznawania znaków (OCR). visionText jest używany w połączeniu z warunkiem element_present . Wzajemnie wykluczające się z elementDescriptors . |
Poniżej znajduje się przykład skryptu Robo uruchamianego przez widżet interfejsu użytkownika z identyfikatorem zasobu "my.app.package:id/page_header"
widocznym na ekranie:
{
"id": 1000,
"contextDescriptor": {
"condition": "element_present",
"elementDescriptors": [
{
"resourceId": "my.app.package:id/page_header"
}
]
},
"actions": [
{
"eventType": "VIEW_CLICKED",
"elementDescriptors": [
{
"text": "Settings"
}
]
}
]
}
Poniżej znajduje się przykład skryptu Robo, który jest wyzwalany przez "Privacy Policy"
wykrytą przez optyczne rozpoznawanie znaków (OCR):
{
"id": 1000,
"description": "Vision text Robo script",
"contextDescriptor": {
"condition": "element_present",
"visionText": "Privacy Policy"
},
"actions": [
{
"eventType": "VIEW_CLICKED",
"visionText": "Privacy Policy"
}
]
}
Poniżej znajduje się przykład skryptu Robo, który czeka 5 sekund po każdej nieskryptowej akcji Robo:
{
"contextDescriptor": {
"condition": "non_roboscript_action_performed"
},
"maxNumberOfRuns" : 1000,
"actions" : [
{
"eventType" : "DELAYED_MESSAGE_POSTED",
"delayTime" : 5000
}]
}
działania
Każda akcja w skrypcie Robo jest reprezentowana jako wiązka jednej lub więcej par atrybut-wartość, które są opisane w poniższej tabeli:
Atrybut | Opis |
eventType | Określa typ akcji, np. kliknięcie, edycja tekstu itp. Wymagane dla każdej akcji. |
elementDescriptors | Deskryptory identyfikujące widżet interfejsu użytkownika. Wymagane dla wszystkich działań, które mają docelowy widżet interfejsu użytkownika, np. kliknięcie określonego przycisku. |
optional | Jeśli jest ustawiona na true , ta akcja jest pomijana, gdy nie można jej wykonać. Na przykład ta akcja jest pomijana, gdy nie może znaleźć docelowego widżetu interfejsu użytkownika na ekranie – bez niepowodzenia zawierającego go skryptu Robo. Domyślnie wartością jest false . |
replacementText | Tekst do wprowadzenia w docelowym widżecie interfejsu użytkownika. Wymagane do działań związanych z edycją tekstu. |
swipeDirection | Określa kierunek przesunięcia. Wymagane do akcji przesuwania. |
delayTime | Określa czas oczekiwania w milisekundach. Wymagane dla akcji oczekiwania. |
pointTapXCoordinate i pointTapYCoordinate | Współrzędne X i Y piksela stukniętego punktu. Wzajemnie wykluczające się z pointTapXPercent i pointTapYPercent . Wymagane do akcji typu point tap. |
pointTapXPercent i pointTapYPercent | Współrzędne procentowe X i Y punktu stuknięcia. Wzajemnie wykluczające się z pointTapXCoordinate i pointTapYCoordinate . Wymagane do akcji typu point tap. |
Poniżej znajduje się przykład skryptu Robo z dwiema akcjami bez docelowych widżetów interfejsu użytkownika, co oznacza, że te akcje nie działają na określonym widżecie interfejsu użytkownika:
[
{
"eventType": "DELAYED_MESSAGE_POSTED",
"delayTime": 3000
},
{
"eventType": "PRESSED_BACK"
}
]
Deskryptory elementów
Deskryptor elementu identyfikuje widżet interfejsu użytkownika za pomocą co najmniej jednego z następujących atrybutów identyfikujących:
Atrybut | Opis |
className | – |
ancestorClassName | Nazwa klasy przodka hierarchii interfejsu użytkownika elementu. Przodkiem jest dowolny z węzłów nadrzędnych w hierarchii interfejsu użytkownika elementu, w tym sam element. |
resourceId | – |
resourceIdRegex | Wyrażenie regularne Java pasujące do resourceId . |
contentDescription | – |
contentDescriptionRegex | Wyrażenie regularne Java pasujące do contentDescription . |
text (który pojawia się na ekranie) | – |
textRegex | Wyrażenie regularne Java pasujące do text . |
groupViewChildPosition , recyclerViewChildPosition lub adapterViewChildPosition | Reprezentuje pozycję podrzędną widżetu interfejsu użytkownika w zależności od rodzaju widżetu nadrzędnego. |
Często te atrybuty są niezdefiniowane, na przykład przycisk może nie mieć tekstu i opisu treści. Nawet jeśli niektóre wartości atrybutów są obecne, mogą nie być unikatowe na danym ekranie aplikacji (w tym resourceId
).
Na przykład rozróżnienie między elementami listy jest zwykle możliwe tylko przy użyciu ich różnych pozycji podrzędnych w ich widgecie nadrzędnym. Oznacza to, że użycie tylko jednego deskryptora elementu do identyfikacji widżetu interfejsu użytkownika jest zwykle niewystarczające. W związku z tym atrybut elementDescriptors
akcji zawiera sekwencję deskryptorów elementów uporządkowanych w taki sposób, że pierwszy odpowiada docelowemu widżetowi interfejsu użytkownika, drugi odpowiada widżetowi nadrzędnemu docelowego widżetu interfejsu użytkownika itd. Docelowy widżet interfejsu użytkownika akcji jest dopasowany, gdy wszystkie jego deskryptory elementów pasują do odpowiedniej podhierarchii widżetu interfejsu użytkownika.
Poniżej znajduje się przykład skryptu Robo ze zmianą tekstu i kliknięciem, z których oba wymagają zidentyfikowania docelowego widżetu interfejsu użytkownika za pomocą dostarczonych deskryptorów elementów:
[
{
"eventType": "VIEW_TEXT_CHANGED",
"replacementText": "John",
"elementDescriptors": [
{
"className": "android.support.v7.widget.AppCompatEditText",
"groupViewChildPosition": 0,
"resourceId": "com.google.samples.apps.topeka:id/first_name"
},
{
"className": "android.widget.FrameLayout",
"groupViewChildPosition": 0
},
{
"className": "android.support.design.widget.TextInputLayout",
"groupViewChildPosition": 1
}
]
},
{
"eventType": "VIEW_CLICKED",
"elementDescriptors": [
{
"className": "android.support.design.widget.FloatingActionButton",
"groupViewChildPosition": 1,
"resourceId": "com.google.samples.apps.topeka:id/done"
},
{
"className": "android.widget.FrameLayout",
"groupViewChildPosition": 1,
"resourceId": "com.google.samples.apps.topeka:id/content"
},
{
"className": "android.widget.FrameLayout",
"groupViewChildPosition": 0,
"resourceId": "com.google.samples.apps.topeka:id/sign_in_content"
}
]
}
]
Opcje wykonania
Opcjonalnie możesz poprzedzić listę akcji w skrypcie Robo obiektem JSON, który określa opcje wykonania dla tego skryptu Robo. Ten nagłówek konfiguracji zaczyna się od słowa kluczowego roboscript
, po którym następuje reprezentacja JSON żądanych opcji wykonania.
Skrypty Robo obsługują następujące opcje wykonania:
-
executionMode
- opcje wykonania stosowane podczas działania skryptu Robo:-
strict
— jeśli ustawione natrue
, skrypt Robo nie stosuje częściowego dopasowania, pomijania bieżącej akcji i zawieszania . Oznacza to, że skrypt Robo jest wykonywany jako zwykły test oprzyrządowania i kończy się niepowodzeniem, gdy tylko nie można wykonać żadnej z jego akcji.
-
-
postscript
- opcje wykonania zastosowane po wykonaniu skryptu Robo:-
terminate
— jeśli ustawiono natrue
, test Robo zatrzymuje indeksowanie po zakończeniu skryptu Robo.
-
Poniżej znajduje się przykład skryptu Robo wykonanego w trybie strict
, który jest uśpiony przez trzy sekundy, po czym indeksowanie zostaje zatrzymane:
"roboscript": {
"executionMode": {
"strict": true
},
"postscript": {
"terminate": true
}
}
[
{
"eventType": "DELAYED_MESSAGE_POSTED",
"delayTime": 3000
}
]
Parametry szablonu
Parametr szablonu to symbol zastępczy w skrypcie Robo, który jest zastępowany rzeczywistą wartością, gdy test Robo ładuje ten skrypt Robo do wykonania. Parametry szablonu są poprzedzone podwójnym podkreśleniem, po którym następuje znak procentu, i są poprzedzone znakiem procentu, po którym następuje podwójne podkreślenie.
Skrypty Robo obsługują następujący parametr szablonu:
-
__%APP_PACKAGE_NAME%__
— nazwa pakietu testowanej aplikacji.
Poniżej znajduje się przykład skryptu Robo, który zatrzymuje proces testowania aplikacji:
[
{
"eventType": "ADB_SHELL_COMMAND",
"command": "am force-stop __%APP_PACKAGE_NAME%__"
}
]
Uwagi
Skrypt Robo może zawierać linie komentarza, które zaczynają się od #
lub //
.
Poniżej znajduje się przykład skryptu Robo z kilkoma komentarzami:
# Confirm a user account.
[
{
// Click the DONE button.
"eventType": "VIEW_CLICKED",
"elementDescriptors": [
{
"resourceId": "com.google.samples.apps.topeka:id/done"
}
]
}
]
Możliwości
Domyślnie, dopóki wszystkie działania skryptu Robo nie zostaną zakończone (lub przynajmniej podjęte), skrypt Robo pozostaje aktywny. Test Robo próbuje dopasować akcję skryptu Robo za każdym razem, gdy wybiera akcję do wykonania. Skrypt Robo wykorzystuje następujące techniki w celu zwiększenia niezawodności:
Technika | Opis |
Częściowe dopasowanie | Jeśli nie można w pełni dopasować bieżącej akcji skryptu Robo, kryteria dopasowania zostaną złagodzone, a dopasowanie zostanie ponowione. Częściowe dopasowanie nie uwzględnia najbardziej zewnętrznego deskryptora elementu podczas dopasowywania docelowego widżetu interfejsu użytkownika akcji skryptu Robo. Jeśli częściowe dopasowanie powiedzie się, odpowiednia akcja skryptu Robo jest wykonywana jak zwykle. Ta technika obsługuje scenariusze, w których struktura aplikacji zmienia się, na przykład między wersjami aplikacji, gdy elementy ekranu są zmieniane. |
Pomiń bieżącą akcję | Jeśli bieżąca akcja skryptu Robo nie może zostać w pełni lub częściowo dopasowana, Robo próbuje dopasować następną akcję skryptu Robo. Jeśli następna akcja jest całkowicie lub częściowo zgodna, test Robo pomija (i nigdy do niej nie powraca) bieżącą akcję skryptu Robo i wykonuje następną. Ta technika obsługuje scenariusze, w których zachowanie aplikacji zmienia się między wersjami lub jest niestabilne, na przykład gdy sporadyczne okno dialogowe może pojawiać się na różnych ekranach podczas nagrywania i odtwarzania skryptu Robo. |
Wstrzymać | Jeśli ani bieżące, ani kolejne akcje skryptu Robo nie mogą zostać w pełni lub częściowo dopasowane, skrypt Robo zostaje tymczasowo zawieszony, a Robo test wybiera akcję do wykonania przy użyciu innych swoich strategii. Po zakończeniu tej akcji Robo test wznawia wykonywanie skryptu Robo. Dopóki nie można dopasować bieżących lub kolejnych akcji skryptu Robo, skrypt Robo pozostaje zawieszony na dowolną liczbę akcji. W związku z tym skrypty Robo niekoniecznie muszą być prologiem do testu Robo, a akcje skryptu Robo można przeplatać ze standardowymi akcjami testowymi Robo. Ta technika obsługuje scenariusze, w których zachowanie aplikacji jest niestabilne lub gdy zmiany między wersjami aplikacji są na tyle duże, że test Robo musi „wypełnić luki” swoimi standardowymi działaniami. |
Priorytety
Jeśli skrypt Robo osiągnie wartość maxNumberOfRuns
, nie może już zostać uruchomiony w danym przeszukiwaniu. Jeśli bieżący kontekst może uruchomić więcej niż jeden skrypt Robo, pierwszeństwo ma wybór w następującej kolejności skryptu Robo, który:
- Ma atrybut
contextDescriptor
. - Ma najwyższy
priority
(domyślnie wszystkie skrypty Robo mają ten sampriority
wykonania1
). - Pojawia się najwcześniej na liście skryptów Robo, jeśli priorytety skryptów Robo są takie same.
Poniżej znajduje się przykład pliku z trzema skryptami Robo, które wykonują tę samą akcję i są wyzwalane przez ten sam warunek — testowana aplikacja znajduje się na pierwszym planie:
[
{
"id": 1000,
"description": "Robo script 1",
"contextDescriptor": {
"condition": "app_under_test_shown"
},
"actions": [
{
"eventType": "DELAYED_MESSAGE_POSTED",
"delayTime": 3000
}
]
},
{
"id": 1001,
"description": "Robo script 2",
"priority": "2",
"contextDescriptor": {
"condition": "app_under_test_shown"
},
"actions": [
{
"eventType": "DELAYED_MESSAGE_POSTED",
"delayTime": 3000
}
]
},
{
"id": 1002,
"description": "Robo script 3",
"contextDescriptor": {
"condition": "app_under_test_shown"
},
"actions": [
{
"eventType": "DELAYED_MESSAGE_POSTED",
"delayTime": 3000
}
]
}
]
Kiedy testowana aplikacja znajduje się na pierwszym planie, Robo uruchamia następujące czynności w podanej kolejności:
-
"Robo script 2"
, ponieważ ma najwyższy priorytet. -
"Robo script 1"
, ponieważ pojawia się wcześniej wśród pozostałych odpowiednich skryptów Robo o takim samym priorytecie. -
"Robo script 3"
jako ostatni odpowiedni skrypt Robo.
Powtarzające się biegi
Domyślnie Robo uruchamia skrypt Robo najwyżej raz podczas indeksowania. Można to dostosować za pomocą atrybutu maxNumberOfRuns
.
Poniżej znajduje się przykład skryptu Robo, który przełącza testowaną aplikację w tło nawet 10 razy:
{
"id": 1000,
"maxNumberOfRuns": 10,
"contextDescriptor": {
"condition": "app_under_test_shown"
},
"actions": [
{
"eventType": "GO_HOME"
}
]
}
Etap czołgania się
Skrypty Robo mają zastosowanie na różnych etapach danego indeksowania Robo:
Etap czołgania się | Opis |
pre_crawl | Zanim Robo uruchomi się i zacznie indeksować testowaną aplikację. |
post_crawl | Gdy Robo zakończy indeksowanie testowanej aplikacji. |
crawl | Główny etap indeksowania, podczas którego Robo indeksuje testowaną aplikację. |
close_screen | Kiedy Robo próbuje wrócić (wycofać się) z danego ekranu, kiedy zbadane są wszystkie możliwe działania na tym ekranie. Domyślnie Robo naciska, co jest niepożądane w niektórych scenariuszach. |
Jeśli atrybut crawlStage
skryptu Robo nie jest określony, zakłada się, że jest to crawl
.
Poniżej znajduje się przykład skryptu Robo, który czyści dane użytkownika testowanej aplikacji, zanim Robo zacznie je indeksować:
{
"id": 1000,
"crawlStage": "pre_crawl",
"actions": [
{
"eventType": "ADB_SHELL_COMMAND",
"command": "pm clear __%APP_PACKAGE_NAME%__"
}
]
}
Poniżej znajduje się przykład skryptu Robo, który instruuje Robo, aby kliknął "Cancel"
za każdym razem, gdy próbuje wrócić (cofnąć się) z okna dialogowego potwierdzenia:
{
"id": 1000,
"crawlStage": "close_screen",
"maxNumberOfRuns": 999,
"contextDescriptor": {
"condition": "element_present",
"elementDescriptors": [
{
"resourceId": "my.app.package:id/confirmation_dialog"
}
]
},
"actions": [
{
"eventType": "VIEW_CLICKED",
"elementDescriptors": [
{
"text": "Cancel"
}
]
}
]
}
Akcje warunkowe
Skrypt Robo może zawierać akcje warunkowe. Akcje warunkowe mają trzy dodatkowe atrybuty, które opisują, w jaki sposób Robo je wykonuje:
Atrybut | Opis |
priority | Priorytet tej akcji warunkowej w porównaniu z innymi akcjami warunkowymi w zawierającym ją skrypcie Robo. Domyślnie wszystkie akcje warunkowe mają priorytet 1 . |
maxNumberOfRuns | Ile razy można wykonać tę akcję warunkową podczas jednego wykonania zawierającego ją skryptu Robo. Domyślnie wszystkie akcje warunkowe można wykonać najwyżej raz w jednym wykonaniu zawierającego je skryptu Robo. |
contextDescriptor | Kontekst/warunek, który wyzwala to działanie warunkowe. Ma taką samą strukturę i oferuje podobne możliwości jak [deskryptor kontekstu skryptu Robo](#context-descriptor). |
Po uruchomieniu skrypt Robo wykonuje swoje bezwarunkowe akcje jedna po drugiej w kolejności pojawiania się. Jeśli skrypt Robo zawiera akcje warunkowe, są one brane pod uwagę za każdym razem przed wybraniem akcji bezwarunkowej do wykonania. Jeśli jakakolwiek akcja warunkowa zostanie uruchomiona i wybrana na podstawie jej priorytetu i pozostałej liczby uruchomień, skrypt Robo wykona tę akcję warunkową. W przeciwnym razie skrypt Robo wykona następującą bezwarunkową akcję. Aby skrypt Robo był ważny, musi zawierać co najmniej jedną akcję bezwarunkową.
Poniżej znajduje się przykład bezwarunkowego skryptu Robo z akcją warunkową, która odrzuca wyskakujące okna dialogowe, jeśli pojawią się one w dowolnym momencie wykonywania skryptu Robo:
{
"id": 1000,
"actions": [
{
"description": "Dismiss popup",
"maxNumberOfRuns": 100,
"contextDescriptor": {
"condition": "default_launcher_shown",
"negateCondition": true
},
"eventType": "GO_HOME"
},
{
"description": "Screen off",
"eventType": "ADB_SHELL_COMMAND",
"command": "input keyevent 26"
},
{
"description": "Wait for 10 seconds",
"eventType": "DELAYED_MESSAGE_POSTED",
"delayTime": 10000
},
{
"description": "Screen on",
"eventType": "ADB_SHELL_COMMAND",
"command": "input keyevent 82"
},
{
"description": "Wait for 10 seconds",
"eventType": "DELAYED_MESSAGE_POSTED",
"delayTime": 10000
}
}
Ignorowanie działań
Skrypt Robo może zawierać instrukcje dla Robo dotyczące ignorowania określonych widżetów interfejsu użytkownika lub wszystkich widżetów interfejsu użytkownika na określonym ekranie. Te instrukcje są reprezentowane jako ignorujące „akcje” z eventType
ELEMENT_IGNORED
i odpowiednio ALL_ELEMENTS_IGNORED
.
Ilekroć atrybut contextDescriptor
skryptu Robo zawierającego akcje ignorowania pasuje do danego ekranu, Robo nie wchodzi w interakcje z żadnymi widżetami interfejsu użytkownika, na które są skierowane jego akcje ignorowania (chyba że jakaś inna akcja skryptu Robo zmusza Robo do wykonania akcji na jednym z ignorowanych widżetów interfejsu użytkownika).
Skrypt Robo może zawierać kombinację działań ignorujących, warunkowych i bezwarunkowych. W przeciwieństwie do innych akcji skryptu Robo, akcje ignorowania są stosowane, o ile ich zawierający atrybut contextDescriptor
skryptu Robo pasuje do ekranu podczas przeszukiwania Robo, niezależnie od wartości atrybutów priority
i maxNumberOfRuns
.
Poniżej znajduje się przykład pliku z dwoma skryptami Robo. Pierwszy skrypt Robo sprawia, że Robo ignoruje wszystkie widżety interfejsu użytkownika na ekranie zawierającym widżet interfejsu użytkownika z identyfikatorem zasobu "my.app.package:id/ignored_screen"
. Drugi skrypt Robo sprawia, że Robo ignoruje widżety interfejsu użytkownika, których identyfikatory zasobów pasują do wyrażenia regularnego Java ".*:id/done"
na ekranie zawierającym widżet interfejsu użytkownika o identyfikatorze zasobu "my.app.package:id/main_screen"
:
[
{
"id": 1000,
"contextDescriptor": {
"condition": "element_present",
"elementDescriptors": [
{
"resourceId": "my.app.package:id/ignored_screen"
}
]
},
"actions": [
{
"eventType": "ALL_ELEMENTS_IGNORED"
}
]
},
{
"id": 1001,
"contextDescriptor": {
"condition": "element_present",
"elementDescriptors": [
{
"resourceId": "my.app.package:id/main_screen"
}
]
},
"actions": [
{
"eventType": "ELEMENT_IGNORED",
"elementDescriptors": [
{
"resourceIdRegex": ".*:id/done"
}
]
}
]
}
]
Obsługa RecyclerView i AdapterView
Elementy podrzędne widżetów RecyclerView i AdapterView są ładowane dynamicznie i mogą być wyświetlane wiele przeciągnięć od bieżącego ekranu. Ponieważ rozmiar ekranu i liczba przesunięć wymaganych do dotarcia do tego elementu podrzędnego jest różna dla różnych typów urządzeń, o wiele bardziej niezawodne jest poleganie na pozycji danych elementu podrzędnego, która jest bezwzględna. Mniej solidnym podejściem jest poleganie na liczbie przesunięć, które są wymagane, aby przenieść to dziecko na ekran, a następnie użyć jego pozycji na ekranie.
W związku z tym skrypt Robo przechwytuje bezwzględne pozycje danych elementów podrzędnych RecyclerView, które są obiektami docelowymi akcji skryptu Robo jako recyclerViewChildPosition
. Skrypt Robo przechwytuje również bezwzględne pozycje danych elementów podrzędnych AdapterView, które są celem akcji skryptu Robo jako adapterViewChildPosition
.
Akcje na elementach podrzędnych RecyclerView i AdapterView są wykonywane w następujących krokach:
Test Robo zapewnia, że odpowiednie dziecko jest wyświetlane na ekranie poprzez akcję pozycjonowania na jego zawierającym RecyclerView lub AdapterView.
Test Robo wykonuje zarejestrowaną akcję bezpośrednio na elemencie potomnym, ponieważ jest on już wyświetlany na ekranie.
Poniżej znajduje się przykład akcji kliknięcia elementu podrzędnego AdapterView ( android.widget.GridView
):
{
"eventType": "VIEW_CLICKED",
"elementDescriptors": [
{
"className": "com.google.samples.apps.topeka.widget.AvatarView",
"adapterViewChildPosition": 5,
"resourceId": "com.google.samples.apps.topeka:id/avatar",
"contentDescription": "Avatar 6"
},
{
"className": "android.widget.GridView",
"groupViewChildPosition": 1,
"resourceId": "com.google.samples.apps.topeka:id/avatars"
},
{
"className": "android.widget.LinearLayout",
"groupViewChildPosition": 1
},
{
"className": "android.widget.LinearLayout",
"groupViewChildPosition": 0
}
]
}
Poniżej przedstawiono przykład akcji kliknięcia elementu podrzędnego RecyclerView ( android.support.v7.widget.RecyclerView
):
{
"eventType": "VIEW_CLICKED",
"elementDescriptors": [
{
"className": "android.support.v7.widget.AppCompatTextView",
"groupViewChildPosition": 1,
"resourceId": "com.google.samples.apps.topeka:id/category_title"
},
{
"className": "android.widget.FrameLayout",
"recyclerViewChildPosition": 8,
"resourceId": "com.google.samples.apps.topeka:id/category_item"
},
{
"className": "android.support.v7.widget.RecyclerView",
"groupViewChildPosition": 1,
"resourceId": "com.google.samples.apps.topeka:id/categories"
},
{
"className": "android.widget.FrameLayout",
"groupViewChildPosition": 1,
"resourceId": "com.google.samples.apps.topeka:id/category_container"
},
{
"className": "android.widget.LinearLayout",
"groupViewChildPosition": 0
}
]
}
Nagraj skrypt Robo w Android Studio i uruchom go w Test Lab
Możesz utworzyć skrypt Robo w Android Studio, który zapisuje skrypt jako plik JSON. Następnie możesz przesłać plik JSON do Firebase Test Lab wraz z aplikacją i odpowiednio uruchomić test.
Gdy uruchamiasz test Robo z dołączonym skryptem, Robo testuje pierwsze kroki przez wstępnie ustawione działania, a następnie eksploruje aplikację w zwykły sposób.
Aby utworzyć plik JSON skryptu Robo w Android Studio, wykonaj czynności opisane w temacie Rejestrowanie skryptu Robo za pomocą Test Lab w Android Studio .
Akcje skryptu Robo
Następujący wspólny atrybut opcjonalny ma zastosowanie do wszystkich działań:
-
description
— pomaga śledzić wykonanie tej akcji skryptu Robo w wynikach testu Robo.
Twierdzenie
Jeśli potwierdzony warunek jest prawdziwy, skrypt Robo przechodzi do następnej akcji, którą może być kolejna asercja. W przeciwnym razie wykonanie skryptu Robo zostanie zatrzymane z powodu nieudanej asercji.
W poniższej tabeli wymieniono wymagane atrybuty:
Atrybut | Opis |
"eventType": "ASSERTION" | -- |
contextDescriptor | Opisuje potwierdzony kontekst lub warunek. Ma taką samą strukturę i oferuje podobne możliwości jak contextDescriptor skryptu Robo . |
Poniżej znajduje się przykład asercji skryptu Robo, która sprawdza, czy testowana aplikacja znajduje się na pierwszym planie:
{
"eventType": "ASSERTION",
"contextDescriptor": {
"condition": "app_under_test_shown"
}
}
Poniżej znajduje się przykład asercji skryptu Robo, która sprawdza, czy na ekranie znajduje się widżet interfejsu użytkownika o identyfikatorze zasobu "com.google.samples.apps.topeka:id/done"
:
{
"eventType": "ASSERTION",
"contextDescriptor": {
"condition": "element_present",
"elementDescriptors": [
{
"resourceId": "com.google.samples.apps.topeka:id/done"
}
]
}
}
Poniżej znajduje się przykład potwierdzenia skryptu Robo, który sprawdza, czy "Settings"
NIE są wykrywane na ekranie za pomocą OCR:
{
"eventType": "ASSERTION",
"contextDescriptor": {
"condition": "element_present",
"negateCondition": true,
"visionText": "Settings"
}
}
Kliknij
W poniższej tabeli wymieniono wymagane atrybuty:
Atrybut | Opis |
---|---|
eventType | Określa typ akcji skryptu Robo. |
"eventType": "VIEW_CLICKED" | Klika element docelowy testowanej aplikacji. |
"eventType": "SOFT_KEYBOARD_CLICK" | Klika docelowy element klawiatury programowej. |
"eventType": "SOFT_KEYBOARD_RANDOM_CLICK" | Klika losowe elementy klawiatury programowej do maxNumberOfRuns razy. |
"eventType": "LIST_ITEM_CLICKED" | Używany przez rejestrator skryptów Robo w Android Studio do klikania elementów listy. |
elementDescriptors | Identyfikuje kliknięty widżet interfejsu użytkownika za pomocą hierarchii interfejsu użytkownika systemu Android. Wzajemnie wykluczające się z visionText . |
visionText | Identyfikuje kliknięty element za pomocą OCR. Wzajemnie wykluczające się z elementDescriptors . |
maxNumberOfRuns | Określa, ile razy należy kliknąć losowy element klawiatury programowej, gdy eventType jest SOFT_KEYBOARD_RANDOM_CLICK . Wartość domyślna to 1 . |
Poniżej znajduje się przykład działania skryptu Robo, które polega na kliknięciu przycisku o identyfikatorze zasobu "com.google.samples.apps.topeka:id/done"
:
{
"eventType": "VIEW_CLICKED",
"elementDescriptors": [
{
"resourceId": "com.google.samples.apps.topeka:id/done"
}
]
}
Poniżej znajduje się przykład akcji skryptu Robo, która polega na kliknięciu "Privacy Policy"
wykrytej na ekranie za pomocą funkcji OCR:
{
"eventType": "VIEW_CLICKED",
"visionText": "Privacy Policy"
}
Poniżej znajduje się przykład akcji skryptu Robo, która klika element klawiatury programowej z opisem treści "Emoji button"
:
{
"eventType": "SOFT_KEYBOARD_CLICK",
"elementDescriptors": [
{
"contentDescription": "Emoji button"
}
]
}
Poniżej znajduje się przykład akcji skryptu Robo, która klika losowe elementy klawiatury programowej do pięciu razy:
{
"eventType": "SOFT_KEYBOARD_RANDOM_CLICK",
"maxNumberOfRuns": 5
}
Wyłącz klawiaturę programową
W poniższej tabeli wymieniono wymagane atrybuty:
Atrybut | Opis |
"eventType": "DISABLE_KEYBOARD" | -- |
Poniżej znajduje się przykład akcji skryptu Robo, która wyłącza klawiaturę programową:
{
"eventType": "DISABLE_KEYBOARD"
}
Wykonaj polecenie powłoki adb
W poniższej tabeli wymieniono wymagane atrybuty:
Atrybut | Opis |
"eventType": "ADB_SHELL_COMMAND" | -- |
command | Polecenie powłoki Android Debug Bridge (adb) do wykonania. |
Poniżej znajduje się przykład akcji skryptu Robo, która czyści dane użytkownika testowanej aplikacji:
{
"eventType": "ADB_SHELL_COMMAND",
"command": "pm clear __%APP_PACKAGE_NAME%__"
}
Przyznaj uprawnienia
To działanie jest rejestrowane przez rejestrator skryptów Robo w Android Studio w celu zapewnienia wstecznej zgodności z Espresso Test Recorder . Robo test przyznaje wszystkie uprawnienia testowanej aplikacji na początku każdego indeksowania, dlatego ta czynność jest niewykonalna. NIE używaj tej akcji w swoich skryptach Robo.
W poniższej tabeli wymieniono wymagane atrybuty:
Atrybut | Opis |
"eventType": "PERMISSIONS_REQUEST" | -- |
Ignoruj wszystkie elementy na ekranie
Ta akcja powoduje, że Robo ignoruje wszystkie elementy na każdym ekranie, który uruchamia zawierający skrypt Robo.
W poniższej tabeli wymieniono wymagane atrybuty:
Atrybut | Opis |
"eventType": "ALL_ELEMENTS_IGNORED" | -- |
Poniżej znajduje się przykład akcji skryptu Robo, która sprawia, że Robo ignoruje wszystkie elementy na ekranie:
{
"eventType": "ALL_ELEMENTS_IGNORED"
}
Ignoruj element
To działanie powoduje, że Robo ignoruje element (lub elementy), które pasują do określonego elementDescriptors
.
W poniższej tabeli wymieniono wymagane atrybuty:
Atrybut | Opis |
"eventType": "ELEMENT_IGNORED" | -- |
elementDescriptors | Identyfikuje ignorowane widżety interfejsu użytkownika przy użyciu hierarchii interfejsu użytkownika systemu Android. |
Poniżej znajduje się przykład akcji skryptu Robo, która sprawia, że Robo ignoruje wszystkie elementy, których opisy zawartości zaczynają się od "Avatar"
:
{
"eventType": "ELEMENT_IGNORED",
"elementDescriptors": [
{
"contentDescriptionRegex": "Avatar.*"
}
]
}
Wprowadź tekst
W poniższej tabeli wymieniono wymagane atrybuty:
Atrybut | Opis |
---|---|
eventType | Określa typ akcji skryptu Robo. |
"eventType": "VIEW_TEXT_CHANGED" | Wprowadza podany tekst do docelowego widżetu interfejsu użytkownika. |
"eventType": "ENTER_TEXT" | wprowadza podany tekst do docelowego widżetu interfejsu użytkownika, a następnie wysyła zdarzenie KEYCODE_ENTER do tego widżetu interfejsu użytkownika. |
elementDescriptors | Identyfikuje docelowy widżet interfejsu użytkownika przy użyciu hierarchii interfejsu użytkownika systemu Android. |
replacementText | Tekst do wprowadzenia w docelowym widżecie interfejsu użytkownika. |
Poniżej znajduje się przykład akcji skryptu Robo, która wprowadza "John"
do widżetu interfejsu użytkownika z identyfikatorem zasobu "com.google.samples.apps.topeka:id/first_name"
:
{
"eventType": "VIEW_TEXT_CHANGED",
"replacementText": "John",
"elementDescriptors": [
{
"resourceId": "com.google.samples.apps.topeka:id/first_name"
}
]
}
Długie kliknięcie
W poniższej tabeli wymieniono wymagane atrybuty:
Atrybut | Opis |
"eventType": "VIEW_LONG_CLICKED" | -- |
elementDescriptors | Identyfikuje docelowy widżet interfejsu użytkownika przy użyciu hierarchii interfejsu użytkownika systemu Android. |
Następujący atrybut jest opcjonalny:
-
delayTime
- określa, jak długo trwa naciśnięcie długiego kliknięcia w milisekundach.
Poniżej przedstawiono przykład działania skryptu Robo, który wykonuje pięciosekundowe kliknięcie widżetu interfejsu użytkownika z opisem treści "Avatar 8"
:
{
"eventType": "VIEW_LONG_CLICKED",
"elementDescriptors": [
{
"contentDescription": "Avatar 8"
}
],
"delayTime": 5000
}
Wykonaj jednopunktowy gest
W poniższej tabeli wymieniono wymagane atrybuty:
Atrybut | Opis |
---|---|
"eventType": "ONE_POINT_GESTURE" | -- |
coordinates | Dwie współrzędne dla gestu jednopunktowego, sformatowane jako „(x1,y1)->(x2,y2)” jako wartości procentowe lub piksele. |
Następujący atrybut jest opcjonalny:
-
dragAndDrop
— jeśli jest ustawiona natrue
, gest jednopunktowy wykonuje akcję przeciągania i upuszczania. Domyślnie jest tofalse
.
Poniżej znajduje się przykład jednopunktowego gestu skryptu Robo, który wykonuje przesunięcie w dół:
{
"eventType": "ONE_POINT_GESTURE",
"coordinates": "(50%,25%)->(50%,75%)"
}
Wykonaj dwupunktowy gest
W poniższej tabeli wymieniono wymagane atrybuty:
Atrybut | Opis |
---|---|
"eventType": "TWO_POINT_GESTURE" | -- |
coordinates | Cztery współrzędne gestu dwupunktowego, sformatowane jako „(x1,y1)->(x2,y2),(x3,y3)->(x4,y4)” jako wartości procentowe lub piksele. |
Poniżej znajduje się przykład akcji skryptu Robo, która wykonuje gest uszczypnięcia:
{
"eventType": "TWO_POINT_GESTURE",
"coordinates": "(50%,50%)->(25%,50%),(50%,50%)->(75%,50%)"
}
Wykonaj czynność IME
Ta akcja powoduje naciśnięcie przycisku bieżącej akcji, na przykład dalej, gotowe i wyszukaj, w edytorze metod wprowadzania (IME) dla określonego docelowego widżetu interfejsu użytkownika.
W poniższej tabeli wymieniono wymagane atrybuty:
Atrybut | Opis |
---|---|
"eventType": "PRESSED_EDITOR_ACTION" | -- |
elementDescriptors | Identyfikuje docelowy widżet interfejsu użytkownika przy użyciu hierarchii interfejsu użytkownika systemu Android. |
Poniżej przedstawiono przykład działania skryptu Robo, który wykonuje działanie edytora IME na widżecie interfejsu użytkownika o identyfikatorze zasobu "com.google.samples.apps.topeka:id/first_name"
:
{
"eventType": "PRESSED_EDITOR_ACTION",
"elementDescriptors": [
{
"resourceId": "com.google.samples.apps.topeka:id/first_name"
}
]
}
Naciśnij wstecz
W poniższej tabeli wymieniono wymagane atrybuty:
Atrybut | Opis |
eventType | Określa typ akcji skryptu Robo. |
"eventType": "PRESSED_BACK" | Wysyła zdarzenie KEYCODE_BACK do urządzenia. |
"eventType": "PRESSED_BACK_EMULATOR_28" | Używany przez rejestrator skryptów Robo w Android Studio do naciskania wstecz na emulatory API 28. |
Poniżej znajduje się przykład akcji skryptu Robo, która naciska wstecz:
{
"eventType": "PRESSED_BACK"
}
Naciśnij do domu
Ta akcja wysyła do urządzenia zdarzenie KEYCODE_HOME
.
W poniższej tabeli wymieniono wymagane atrybuty:
Atrybut | Opis |
"eventType": "GO_HOME" | -- |
Poniżej znajduje się przykład akcji skryptu Robo, która naciska przycisk home:
{
"eventType": "GO_HOME"
}
Przewiń element do widoku
To działanie powoduje, że Robo test przewinie do przodu widżet interfejsu użytkownika pasujący do określonych elementDescriptors
, dopóki widżet interfejsu użytkownika pasujący do określonych childElementDescriptors
nie pojawi się na ekranie lub nie będzie można przewijać przewijanego widżetu lub zostanie osiągnięta maksymalna liczba 50 przewinięć.
W poniższej tabeli wymieniono wymagane atrybuty:
Atrybut | Opis |
"eventType": "ELEMENT_SCROLL_INTO_VIEW" | -- |
elementDescriptors | Identyfikuje przewijany widżet interfejsu użytkownika przy użyciu hierarchii interfejsu użytkownika systemu Android. |
childElementDescriptors | Identyfikuje widżet interfejsu użytkownika, do którego można przewijać przy użyciu hierarchii interfejsu użytkownika systemu Android. |
Poniżej znajduje się przykład akcji skryptu Robo, która przewija widżet interfejsu użytkownika o identyfikatorze zasobu "my.app.package:id/scrollable_card_container"
do momentu pojawienia się na ekranie widżetu interfejsu użytkownika z tekstem "Orange"
(lub nie można już więcej przewijać zostać wykonane lub osiągnięta zostanie maksymalna liczba 50 zwojów):
{
"eventType": "ELEMENT_SCROLL_INTO_VIEW",
"elementDescriptors": [
{
"resourceId": "my.app.package:id/scrollable_card_container"
}
],
"childElementDescriptors": [
{
"text": "Orange"
}
]
}
Trzepnąć
W poniższej tabeli wymieniono wymagane atrybuty:
Atrybut | Opis |
---|---|
"eventType": "VIEW_SWIPED" | -- |
swipeDirection | Określa kierunek przesunięcia:
|
elementDescriptors | Identyfikuje docelowy widżet interfejsu użytkownika przy użyciu hierarchii interfejsu użytkownika systemu Android. |
Poniżej znajduje się przykład akcji skryptu Robo, która przesuwa w górę widżet interfejsu użytkownika o identyfikatorze zasobu "my.app.package:id/custom_content"
:
{
"eventType": "VIEW_SWIPED",
"swipeDirection": "Up",
"elementDescriptors": [
{
"resourceId": "my.app.package:id/custom_content"
}
]
}
Zrobić zrzut ekranu
W poniższej tabeli wymieniono wymagane atrybuty:
Atrybut | Opis |
"eventType": "TAKE_SCREENSHOT" | -- |
screenshotName | Określa nazwę pliku zrzutu ekranu. |
Poniżej znajduje się przykład akcji skryptu Robo, która wykonuje zrzut ekranu:
{
"eventType": "TAKE_SCREENSHOT",
"screenshotName": "my_screenshot"
}
Dotknij punktu na ekranie
W poniższej tabeli wymieniono wymagane atrybuty:
Atrybut | Opis |
---|---|
"eventType": "POINT_TAP" | -- |
pointTapXCoordinate | Współrzędna X piksela stukniętego punktu. Wzajemnie wykluczające się z pointTapXPercent i pointTapYPercent . |
pointTapYCoordinate | Współrzędna Y piksela stukniętego punktu. Wzajemnie wykluczające się z pointTapXPercent i pointTapYPercent . |
pointTapXPercent | Współrzędna procentowa X punktu stuknięcia. Wzajemnie wykluczające się z pointTapXCoordinate i pointTapYCoordinate . |
pointTapYPercent | Współrzędna procentowa Y punktu stuknięcia. Wzajemnie wykluczające się z pointTapXCoordinate i pointTapYCoordinate . |
Poniżej znajduje się przykład akcji skryptu Robo, która dotyka środka ekranu:
{
"eventType": "POINT_TAP",
"pointTapXPercent": 50,
"pointTapYPercent": 50
}
Dotknij punktu w elemencie
W poniższej tabeli wymieniono wymagane atrybuty:
Atrybut | Opis |
"eventType": "POINT_TAP_ELEMENT" | -- |
pointTapXPercent | Współrzędna procentowa X w elemencie docelowym. |
pointTapYPercent | Współrzędna procentowa Y w elemencie docelowym. |
elementDescriptors | Identyfikuje docelowy widżet interfejsu użytkownika za pomocą hierarchii interfejsu użytkownika systemu Android. |
Poniżej znajduje się przykład akcji skryptu Robo, która przesuwa suwak paska wyszukiwania w prawo:
{
"eventType": "POINT_TAP_ELEMENT",
"pointTapXPercent": 80,
"pointTapYPercent": 50,
"elementDescriptors": [
{
"resourceId": "my.app.package:id/my_seekbar"
}
]
}
Zakończ indeksowanie
Ta czynność zatrzymuje test Robo.
W poniższej tabeli wymieniono wymagane atrybuty:
Atrybut | Opis |
---|---|
"eventType": "TERMINATE_CRAWL" | -- |
Poniżej znajduje się przykład akcji skryptu Robo, która zatrzymuje test Robo:
{
"eventType": "TERMINATE_CRAWL"
}
Czekać
W poniższej tabeli wymieniono wymagane atrybuty:
Atrybut | Opis |
"eventType": "DELAYED_MESSAGE_POSTED" | -- |
delayTime | Określa czas oczekiwania w milisekundach. |
Poniżej znajduje się przykład akcji skryptu Robo, która czeka przez trzy sekundy:
{
"eventType": "DELAYED_MESSAGE_POSTED",
"delayTime": 3000
}
Poczekaj na element
Ta akcja powoduje, że Robo test czeka na pojawienie się elementu na ekranie do określonego limitu czasu.
W poniższej tabeli wymieniono wymagane atrybuty:
Atrybut | Opis |
"eventType": "WAIT_FOR_ELEMENT" | -- |
delayTime | Określa limit czasu oczekiwania w milisekundach. |
elementDescriptors | Identyfikuje oczekiwany widżet interfejsu użytkownika przy użyciu hierarchii interfejsu użytkownika systemu Android. |
Poniżej przedstawiono przykład akcji skryptu Robo, która czeka do 30 sekund na pojawienie się na ekranie widżetu interfejsu użytkownika z identyfikatorem zasobu "my.app.package:id/confirmation_button"
:
{
"eventType": "WAIT_FOR_ELEMENT",
"delayTime": 30000,
"elementDescriptors": [
{
"resourceId": "my.app.package:id/confirmation_button"
}
]
}