Robo 스크립트 참조 가이드

이 문서에서는 Robo 스크립트의 구조, 기능, 사용, 기록, 작업을 비롯한 참조 정보를 제공합니다. Robo 스크립트는 모바일 앱의 수동 품질 보증(QA) 작업을 자동화하고 지속적 통합(CI) 및 사전 출시 테스트 전략을 사용 설정하는 테스트입니다. Robo 스크립트는 사용자 인터페이스(UI) 및 기타 작업 시퀀스를 설명하는 JSON 파일입니다.

다음과 같은 방법으로 Robo 스크립트를 만들 수 있습니다.

  • Robo 스크립트 기록 기능을 사용합니다.
  • Robo 스크립트를 수동으로 만듭니다.
  • Robo 스크립트를 기록한 후 수동으로 수정합니다.

Robo 스크립트 사용에 대한 자세한 내용은 Robo 스크립트 실행을 참조하세요.

Robo 스크립트는 Robo 테스트에서 앱 테스트 중인 Android 애플리케이션 패키지(APK)와 같은 다른 입력과 함께 제공됩니다.

다음은 사용자를 앱에 로그인하는 Robo 스크립트의 예입니다. 이 스크립트는 테스트 중인 앱이 실행될 때 트리거됩니다.

[
  {
    "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"
          }
        ]
      }
    ]
  }
]

파일에 Robo 스크립트가 한 개이고 기본 app_under_test_shown 트리거 조건이 있는 경우 위 예와 같이 더 간단한 형식을 사용하여 파일에서 Robo 스크립트를 작업의 시퀀스로 지정할 수 있습니다.

[
  {
    "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"
      }
    ]
  }
]

구조

Robo 스크립트에는 Robo 스크립트를 실행하는 방법을 설명하는 여러 속성이 있습니다. 이러한 대부분의 속성은 사전 정의된 기본값이 있는 선택사항입니다.

속성 설명
id 크롤링 출력에서 이 Robo 스크립트를 추적하는 데 도움이 되는 정수입니다.
description id와 유사하지만 더 구체적입니다.
crawlStage 크롤링 Robo 단계에서는 이 Robo 스크립트를 적용합니다. 기본적으로 기본 크롤링 단계입니다.
priority 다른 Robo 스크립트와 비교한 이 Robo 스크립트의 우선순위입니다. 기본적으로 모든 Robo 스크립트의 우선순위는 1입니다.
maxNumberOfRuns 크롤링 Robo에서 이 Robo 스크립트를 실행할 수 있는 횟수를 지정합니다. 기본적으로 Robo에서 Robo 스크립트를 한 번 실행할 수 있습니다.
contextDescriptor 이 Robo 스크립트를 트리거하는 컨텍스트/조건을 설명합니다. 생략하면 이 Robo 스크립트의 트리거 조건이 항상 충족되는 것으로 간주됩니다. 즉, Robo 스크립트는 비조건부입니다.
actions 이 Robo 스크립트의 모든 작업입니다.

단일 파일에는 하나 이상의 Robo 스크립트 컬렉션이 포함됩니다.

다음은 비조건부 Robo 스크립트가 두 개 있는 파일의 예로, 각 스크립트에는 크롤링 시작 시 한 번 실행되는 단일 작업이 있습니다.

[
  {
    "id": 1000,
    "description": "My first Robo script",
    "actions": [
      {
        "eventType": "DISABLE_KEYBOARD"
      }
    ]
  },
  {
    "id": 1001,
    "description": "My second Robo script",
    "actions": [
      {
        "eventType": "PRESSED_BACK"
      }
    ]
  }
]

컨텍스트 설명어

컨텍스트 설명어는 여러 속성 중 하나 또는 조합을 사용하여 Robo 스크립트를 트리거하는 컨텍스트/조건을 정의합니다.

속성 설명
"condition": "element_present" elementDescriptors와 일치하는 UI 위젯이나 visionText로 지정된 텍스트가 화면에 표시되어 있는지 확인합니다.
"condition": "element_disabled" elementDescriptors와 일치하는 UI 위젯이 화면에 표시되어 있지만 상호작용할 수 없는지 확인합니다.
"condition": "element_checked" elementDescriptors와 일치하는 UI 위젯이 화면에 표시되고 선택되는지 확인합니다.
"condition": "app_under_test_shown" 테스트 중인 앱이 포그라운드에서 실행되고 있는지 확인합니다.
"condition": "default_launcher_shown" 기기의 홈 화면이 표시되는지 확인합니다. 즉, 포그라운드에서 실행 중인 앱이 없음을 의미합니다.
"condition": "non_roboscript_action_performed" Robo 테스트에서 마지막으로 수행한 작업이 Robo 스크립트 작업이 아닌지 확인합니다.
negateCondition true로 설정하면 condition이 무효화됩니다. 예를 들어 이 속성을 사용하여 UI 위젯이 화면에 없거나 테스트 중인 앱이 포그라운드에서 실행되고 있지 않은지 확인할 수 있습니다.
elementDescriptors 화면에서 UI 위젯을 식별하는 하나 이상의 요소 설명어입니다. element_present, element_disabled, element_checked 조건과 함께 사용됩니다. visionText와 상호 배타적입니다. 자세한 내용은 요소 설명어를 참조하세요.
visionText 화면의 텍스트는 광학 문자 인식(OCR) API를 사용하여 감지됩니다. visionTextelement_present 조건과 함께 사용됩니다. elementDescriptors와 상호 배타적입니다.

다음은 리소스 ID가 "my.app.package:id/page_header"인 UI 위젯에 의해 트리거되는 Robo 스크립트의 예입니다.

{
  "id": 1000,
  "contextDescriptor": {
    "condition": "element_present",
    "elementDescriptors": [
      {
        "resourceId": "my.app.package:id/page_header"
      }
    ]
  },
  "actions": [
    {
      "eventType": "VIEW_CLICKED",
      "elementDescriptors": [
        {
          "text": "Settings"
        }
      ]
    }
  ]
}

다음은 광학 문자 인식(OCR)에서 감지한 "Privacy Policy"로 트리거되는 Robo 스크립트의 예입니다.

{
  "id": 1000,
  "description": "Vision text Robo script",
  "contextDescriptor": {
    "condition": "element_present",
    "visionText": "Privacy Policy"
  },
  "actions": [
    {
      "eventType": "VIEW_CLICKED",
      "visionText": "Privacy Policy"
    }
  ]
}

다음은 스크립트가 아닌 모든 Robo 작업 후 5초 동안 기다리는 Robo 스크립트의 예입니다.

{
  "contextDescriptor": {
    "condition": "non_roboscript_action_performed"
  },
  "maxNumberOfRuns" : 1000,
  "actions" : [
    {
      "eventType" : "DELAYED_MESSAGE_POSTED",
      "delayTime" : 5000
    }]
}

작업

Robo 스크립트의 각 작업은 다음 표에 설명된 하나 이상의 속성-값 쌍 번들로 표시됩니다.

속성 설명
eventType 클릭, 텍스트 수정 등 작업의 유형을 지정합니다. 모든 작업에 필요합니다.
elementDescriptors UI 위젯을 식별하는 설명어입니다. 특정 버튼 클릭처럼 대상 UI 위젯이 있는 모든 작업에 필요합니다.
optional true로 설정하면 이 작업을 실행할 수 없을 때 건너뜁니다. 예를 들어 이 작업이 포함된 Robo 스크립트를 실패하지 않고 화면에서 대상 UI 위젯을 찾을 수 없는 경우 건너뜁니다. 기본값은 false입니다.
replacementText 대상 UI 위젯에 입력할 텍스트입니다. 텍스트 수정 작업에 필요합니다.
swipeDirection 스와이프 방향을 지정합니다. 스와이프 작업에 필요합니다.
delayTime 대기 시간(밀리초)을 지정합니다. 대기 작업에 필요합니다.
pointTapXCoordinate, pointTapYCoordinate 탭한 지점의 픽셀 X 및 Y 좌표입니다. pointTapXPercentpointTapYPercent와 상호 배타적입니다. 지점 탭 작업에 필요합니다.
pointTapXPercent, pointTapYPercent 탭한 지점의 백분율 X 및 Y 좌표입니다. pointTapXCoordinatepointTapYCoordinate와 상호 배타적입니다. 지점 탭 작업에 필요합니다.

다음은 대상 UI 위젯 없이 두 작업이 포함된 Robo 스크립트의 예입니다. 즉, 이러한 작업은 특정 UI 위젯에서 작동하지 않습니다.

[
  {
    "eventType": "DELAYED_MESSAGE_POSTED",
    "delayTime": 3000
  },
  {
    "eventType": "PRESSED_BACK"
  }
]

요소 설명어

요소 설명어는 다음 식별 속성 중 하나 이상을 사용하여 UI 위젯을 식별합니다.

속성 설명
className
ancestorClassName 요소의 UI 계층 구조 상위의 클래스 이름입니다. 상위는 요소 자체를 포함하는 요소의 UI 계층 구조에 있는 모든 상위 노드입니다.
resourceId
resourceIdRegex resourceId와 일치하는 Java 정규 표현식입니다.
contentDescription
contentDescriptionRegex contentDescription과 일치하는 Java 정규 표현식입니다.
text(화면에 표시되는 항목)
textRegex text와 일치하는 Java 정규 표현식입니다.
groupViewChildPosition, recyclerViewChildPosition 또는 adapterViewChildPosition 상위 위젯의 종류에 따라 UI 위젯의 하위 위치를 나타냅니다.

이러한 속성은 정의되지 않은 경우가 많습니다. 예를 들어 버튼에 텍스트와 콘텐츠 설명이 없을 수 있습니다. 일부 속성 값이 있더라도 resourceId를 포함하여 특정 앱 화면에서 고유하지 않을 수 있습니다.

예를 들어 목록의 항목을 구별하는 것은 일반적으로 상위 위젯 내에서 다른 하위 위치를 사용하는 경우에만 가능합니다. 즉, 일반적으로 하나의 요소 설명어를 사용하여 UI 위젯을 식별하는 것만으로는 충분하지 않습니다. 따라서 작업의 elementDescriptors 속성은 첫 번째 항목이 대상 UI 위젯에 해당하고 두 번째는 대상 UI 위젯의 상위 위젯에 해당하는 식으로 순서가 지정된 일련의 요소 설명어가 포함됩니다. 작업의 대상 UI 위젯은 모든 요소 설명어가 해당 UI 위젯 하위 계층 구조와 일치할 때 일치됩니다.

다음은 텍스트 변경 및 클릭 작업이 포함된 Robo 스크립트의 예입니다. 두 가지 모두 제공된 요소 설명어를 사용하여 대상 UI 위젯을 식별해야 합니다.

[
  {
    "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"
      }
    ]
  }
]

실행 옵션

Robo 스크립트의 실행 옵션을 지정하는 JSON 객체를 사용해 Robo 스크립트의 작업 목록에 프리픽스를 추가할 수도 있습니다. 이 구성 헤더는 roboscript 키워드로 시작하고 원하는 실행 옵션의 JSON 표현으로 이어집니다.

Robo 스크립트는 다음 실행 옵션을 지원합니다.

  • executionMode - Robo 스크립트가 실행 중일 때 적용되는 실행 옵션입니다.
    • strict - true로 설정하면 Robo 스크립트가 부분 일치, 현재 작업 건너뛰기, 정지를 사용하지 않습니다. 즉, Robo 스크립트가 일반 계측 테스트로 실행되고 작업을 수행할 수 없으면 바로 실패합니다.
  • postscript - Robo 스크립트가 완료된 후 적용되는 실행 옵션입니다.
    • terminate - true로 설정하면 Robo 스크립트가 완료된 후 Robo 테스트에서 크롤링을 중지합니다.

다음은 크롤링이 중지된 후 3초 동안 절전 모드를 유지하는 strict 모드에서 실행된 Robo 스크립트의 예입니다.

"roboscript": {
  "executionMode": {
    "strict": true
  },
  "postscript": {
    "terminate": true
  }
}
[
  {
    "eventType": "DELAYED_MESSAGE_POSTED",
    "delayTime": 3000
  }
]

템플릿 매개변수

템플릿 매개변수는 Robo 테스트에서 Robo 스크립트가 실행될 때 실제 값으로 교체되는 Robo 스크립트의 자리표시자입니다. 템플릿 매개변수 앞에는 이중 밑줄과 퍼센트 기호가 붙고 뒤에는 퍼센트 기호와 이중 밑줄이 붙습니다.

Robo 스크립트는 다음 템플릿 매개변수를 지원합니다.

  • __%APP_PACKAGE_NAME%__ - 테스트 중인 앱의 패키지 이름입니다.

다음은 테스트 중인 앱을 중지하는 Robo 스크립트의 예입니다.

[
  {
    "eventType": "ADB_SHELL_COMMAND",
    "command": "am force-stop __%APP_PACKAGE_NAME%__"
  }
]

주석

Robo 스크립트에는 # 또는 //로 시작하는 줄인 주석 줄이 포함될 수 있습니다.

다음은 몇 가지 주석이 포함된 Robo 스크립트의 예입니다.

# Confirm a user account.
[
  {
    // Click the DONE button.
    "eventType": "VIEW_CLICKED",
    "elementDescriptors": [
      {
        "resourceId": "com.google.samples.apps.topeka:id/done"
      }
    ]
  }
]

기능

기본적으로 Robo 스크립트의 모든 작업이 완료되거나 적어도 시도될 때까지 Robo 스크립트는 활성 상태로 유지됩니다. Robo 테스트에서는 수행할 작업을 선택할 때마다 Robo 스크립트 작업을 일치시키려고 계속 시도합니다. Robo 스크립트는 견고성을 높이기 위해 다음 기법을 사용합니다.

기법 설명
부분 일치 현재 Robo 스크립트 작업을 완전히 일치시킬 수 없는 경우 일치 기준이 완화되고 일치를 다시 시도합니다. 부분 일치는 Robo 스크립트 작업의 대상 UI 위젯을 일치시키는 동안 가장 바깥쪽 요소 설명어를 고려하지 않습니다.

부분 일치가 성공하면 관련 Robo 스크립트 작업이 평상시처럼 실행됩니다. 이 기법은 앱 버전 간에 화면 요소가 다시 정렬되는 등 앱 구조가 변경되는 경우의 시나리오를 지원합니다.

현재 작업 건너뛰기 현재 Robo 스크립트 작업이 완전히 또는 부분적으로 일치될 수 없는 경우 Robo는 후속 Robo 스크립트 작업과 일치시키려고 시도합니다. 후속 작업이 완전히 또는 부분적으로 일치하는 경우 Robo 테스트는 현재 Robo 스크립트 작업을 건너뛰고(다시 돌아가지 않음) 후속 작업을 수행합니다.

이 기법은 앱 동작이 버전 간에 변경되거나 불안정한 시나리오를 지원합니다. 예를 들어 Robo 스크립트를 기록하는 동안과 재생하는 동안 간헐적인 대화상자가 다른 화면에 나타날 수 있습니다.

정지 현재 또는 후속 Robo 스크립트 작업 중 어느 쪽도 완전히 또는 부분적으로 일치될 수 없는 경우 Robo 스크립트가 일시적으로 정지되고 Robo 테스트에서 다른 전략을 사용하여 수행할 작업을 선택합니다. 이 작업이 완료되면 Robo 테스트에서 Robo 스크립트 실행을 재개합니다.

현재 또는 후속 Robo 스크립트 작업과 일치될 수 없으면 많은 작업에서 Robo 스크립트가 정지된 상태로 유지됩니다. 따라서 Robo 스크립트가 Robo 테스트에서 프롤로그가 아니어도 되며 표준 Robo 테스트 작업과 Robo 스크립트 작업을 섞어서 사용할 수 있습니다. 이 기법은 앱 동작이 불안정하거나 앱 버전 간의 변경사항이 Robo 테스트에서 표준 작업으로 '격차를 채워야 할 만큼' 충분히 많은 경우의 시나리오를 지원합니다.

우선순위

Robo 스크립트가 maxNumberOfRuns에 도달하면 더 이상 지정된 크롤링에서 트리거될 수 없습니다. 현재 컨텍스트에서 Robo 스크립트가 2개 이상 트리거될 수 있는 경우 다음 순서에 따라 Robo 스크립트에 우선순위가 부여됩니다.

  1. contextDescriptor 속성이 있습니다.
  2. priority가 가장 높습니다. 기본적으로 모든 Robo 스크립트의 실행 priority1입니다.
  3. Robo 스크립트의 우선순위가 동일한 경우 Robo 스크립트 목록에서 가장 먼저 표시된 스크립트입니다.

다음은 동일한 작업을 수행하고 동일한 조건(테스트 중인 앱이 포그라운드 상태)에 의해 트리거되는 세 가지 Robo 스크립트가 포함된 파일의 예입니다.

[
  {
    "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
      }
    ]
  }
]

테스트 중인 앱이 포그라운드 상태이면 Robo에서 다음을 순서대로 트리거합니다.

  1. "Robo script 2", 우선순위가 가장 높기 때문입니다.
  2. "Robo script 1", 우선순위가 같은 관련 Robo 스크립트 중에서 더 먼저 표시되기 때문입니다.
  3. "Robo script 3", 적용 가능한 마지막 Robo 스크립트이기 때문입니다.

반복 실행

기본적으로 Robo는 크롤링 중에 Robo 스크립트를 최대 한 번 트리거합니다. 이는 maxNumberOfRuns 속성을 통해 조정할 수 있습니다.

다음은 테스트 중인 앱을 백그라운드로 최대 10회 가져오는 Robo 스크립트의 예입니다.

{
  "id": 1000,
  "maxNumberOfRuns": 10,
  "contextDescriptor": {
    "condition": "app_under_test_shown"
  },
  "actions": [
    {
      "eventType": "GO_HOME"
    }
  ]
}

크롤링 단계

Robo 스크립트는 지정된 Robo 크롤링의 여러 단계에 적용됩니다.

크롤링 단계 설명
pre_crawl Robo가 실행되어 테스트 중인 앱의 크롤링을 시작하기 전
post_crawl Robo에서 테스트 중인 앱의 크롤링을 완료한 후
crawl Robo에서 테스트 중인 앱을 크롤링하는 기본 크롤링 단계
close_screen 이 화면에서 가능한 모든 작업을 탐색한 경우 Robo가 특정 화면에서 뒤로 돌아가려고(백트랙) 하는 경우 기본적으로 Robo에서 뒤로 버튼을 누르며, 이는 일부 시나리오에서는 바람직하지 않습니다.

Robo 스크립트의 crawlStage 속성을 지정하지 않으면 crawl인 것으로 간주됩니다.

다음은 Robo에서 크롤링을 시작하기 전에 테스트 중인 앱 사용자 데이터를 삭제하는 Robo 스크립트의 예입니다.

{
  "id": 1000,
  "crawlStage": "pre_crawl",
  "actions": [
    {
      "eventType": "ADB_SHELL_COMMAND",
      "command": "pm clear __%APP_PACKAGE_NAME%__"
    }
  ]
}

다음은 Robo가 확인 대화상자에서 뒤로 돌아가려고(백트랙) 할 때마다 "Cancel"을 클릭하도록 지시하는 Robo 스크립트의 예입니다.

{
  "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"
        }
      ]
    }
  ]
}

조건부 작업

Robo 스크립트에는 조건부 작업이 포함될 수 있습니다. 조건부 작업에는 Robo의 작업 수행 방법을 설명하는 세 가지 추가 속성이 있습니다.

속성 설명
priority 포함된 Robo 스크립트 내의 다른 조건부 작업과 비교한 이 조건부 작업의 우선순위입니다. 기본적으로 모든 조건부 작업의 우선순위는 1입니다.
maxNumberOfRuns 포함된 Robo 스크립트를 한 번 실행하는 동안 이 조건부 작업을 수행할 수 있는 횟수입니다. 기본적으로 모든 조건부 작업은 포함된 Robo 스크립트를 한 번 실행할 때 한 번만 실행할 수 있습니다.
contextDescriptor 이 조건부 작업을 트리거하는 컨텍스트/조건입니다. 구조는 동일하며 [Robo 스크립트의 contextDescriptor](#context-descriptor)와 유사한 기능을 제공합니다.

Robo 스크립트는 트리거될 때 비조건부 작업을 표시된 순서대로 하나씩 수행합니다. Robo 스크립트에 조건부 작업이 포함된 경우 비조건부 작업을 선택하기 전에 매번 고려됩니다. 우선순위와 남은 실행 횟수에 따라 조건부 작업이 트리거되고 선택되면 Robo 스크립트가 이 조건부 작업을 수행합니다. 그러지 않으면 Robo 스크립트가 다음 비조건부 작업을 수행합니다. 유효하려면 Robo 스크립트에 하나 이상의 비조건부 작업이 포함되어야 합니다.

다음은 Robo 스크립트 실행 중에 팝업 대화상자가 표시되면 닫는 조건부 작업이 있는 비조건부 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
    }
}

작업 무시

Robo 스크립트에는 Robo에서 특정 UI 위젯 또는 특정 화면의 모든 UI 위젯을 무시하는 안내가 포함될 수 있습니다. 이러한 안내는 eventType ELEMENT_IGNOREDALL_ELEMENTS_IGNORED를 각각 사용하여 '작업'을 무시하는 것으로 표시됩니다.

무시된 작업이 포함된 Robo 스크립트의 contextDescriptor 속성이 특정 화면과 일치할 때마다 Robo는 무시된 작업으로 타겟팅된 UI 위젯과 상호작용하지 않습니다(다른 Robo 스크립트 작업으로 인해 무시된 UI 위젯 중 하나에서 Robo가 작업을 실행하도록 하는 경우 제외).

Robo 스크립트에는 무시, 조건부, 비조건부 작업이 혼합되어 포함될 수 있습니다. 다른 Robo 스크립트 작업과 달리 무시 작업은 포함된 Robo 스크립트의 contextDescriptorprioritymaxNumberOfRuns 속성 값에 관계없이 Robo 크롤링 중 화면과 일치하는 한 적용됩니다.

다음은 Robo 스크립트 2개가 포함된 파일의 예입니다. 첫 번째 Robo 스크립트를 사용하면 Robo에서 리소스 ID가 "my.app.package:id/ignored_screen"인 UI 위젯이 있는 화면의 모든 UI 위젯을 무시합니다. 두 번째 Robo 스크립트를 사용하면 리소스 ID가 "my.app.package:id/main_screen"인 UI 위젯이 있는 화면에서 리소스 ID가 Java 정규식 ".*:id/done"과 일치하는 UI 위젯을 무시합니다.

[
  {
    "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"
          }
        ]
      }
    ]
  }
]

RecyclerView 및 AdapterView 지원

RecyclerView의 및 AdapterView 위젯의 하위 요소가 동적으로 로드되며 현재 화면에서 여러 번 스와이프해야 표시될 수 있습니다. 화면 크기와 이 하위 요소를 가져오는 데 필요한 스와이프 횟수는 기기 폼 팩터마다 다르며, 하위 요소의 데이터 위치를 사용하는 것이 훨씬 더 강력하고 절대적입니다. 이 하위 요소를 화면에 가져와 화면 위치를 사용하는 데 필요한 스와이프 수에 의존하는 것은 덜 강력한 접근법입니다.

따라서 Robo 스크립트는 recyclerViewChildPosition으로 Robo 스크립트 작업의 대상인 RecyclerView 하위 요소에 대한 절대 데이터 위치를 캡처합니다. 또한 Robo 스크립트는 Robo 스크립트 작업의 대상인 AdapterView 하위 요소의 절대 데이터 위치를 adapterViewChildPosition으로 캡처합니다.

RecyclerView 및 AdapterView 하위 요소의 작업은 다음 단계로 수행됩니다.

  1. Robo 테스트는 RecyclerView 또는 AdapterView를 포함하는 위치 지정 작업을 통해 상응하는 하위 요소가 화면에 표시되는지 확인합니다.

  2. Robo 테스트는 화면에 이미 표시되었으므로 하위 요소에서 직접 기록된 작업을 실행합니다.

다음은 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
    }
  ]
}

다음은 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
    }
  ]
}

Android 스튜디오에서 Robo 스크립트를 기록하고 Test Lab에서 실행

Android 스튜디오에서 Robo 스크립트를 만들어 스크립트를 JSON 파일로 저장할 수 있습니다. 그런 다음 애플리케이션과 함께 JSON 파일을 Firebase Test Lab에 업로드하고 이에 따라 테스트를 실행할 수 있습니다.

스크립트가 첨부된 Robo 테스트를 실행하면 Robo 테스트에서 사전 스크립트 처리된 작업을 먼저 수행한 후 평소와 같이 앱을 탐색합니다.

Android 스튜디오에서 Robo 스크립트 JSON 파일을 만들려면 Android 스튜디오에서 Test Lab을 사용하여 Robo 스크립트 기록의 단계를 따릅니다.

Robo 스크립트 작업

다음 일반적인 선택적 속성은 모든 작업에 적용됩니다.

  • description - Robo 테스트 출력에서 Robo 스크립트 작업 실행을 추적하는 데 도움이 됩니다.

어설션

어설션된 조건이 true이면 Robo 스크립트가 다음 작업으로 넘어갑니다. 이는 다른 어설션일 수 있습니다. 그러지 않으면 어설션 실패로 인해 Robo 스크립트 실행이 중단됩니다.

다음 표에는 필수 속성이 나와 있습니다.

속성 설명
"eventType": "ASSERTION" --
contextDescriptor 어설션된 컨텍스트 또는 조건을 설명합니다. 구조는 동일하며 Robo 스크립트의 contextDescriptor와 유사한 기능을 제공합니다.

다음은 테스트 중인 앱이 포그라운드에 있는지 확인하는 Robo 스크립트 어설션의 예입니다.

{
  "eventType": "ASSERTION",
  "contextDescriptor": {
    "condition": "app_under_test_shown"
  }
}

다음은 리소스 ID가 "com.google.samples.apps.topeka:id/done"인 UI 위젯이 화면에 표시되는지 확인하는 Robo 스크립트 어설션의 예입니다.

{
  "eventType": "ASSERTION",
  "contextDescriptor": {
    "condition": "element_present",
    "elementDescriptors": [
      {
        "resourceId": "com.google.samples.apps.topeka:id/done"
      }
    ]
  }
}

다음은 OCR을 사용하여 "Settings"가 화면에서 감지되는지 확인하는 Robo 스크립트 어설션의 예입니다.

{
  "eventType": "ASSERTION",
  "contextDescriptor": {
    "condition": "element_present",
    "negateCondition": true,
    "visionText": "Settings"
  }
}

클릭

다음 표에는 필수 속성이 나와 있습니다.

속성 설명
eventType Robo 스크립트 작업의 유형을 지정합니다.
"eventType": "VIEW_CLICKED" 테스트 중인 앱의 대상 요소를 클릭합니다.
"eventType": "SOFT_KEYBOARD_CLICK" 소프트 키보드의 대상 요소를 클릭합니다.
"eventType": "SOFT_KEYBOARD_RANDOM_CLICK" 소프트 키보드의 임의 요소를 최대 maxNumberOfRuns회 클릭합니다.
"eventType": "LIST_ITEM_CLICKED" Android 스튜디오의 Robo 스크립트 레코더에서 목록 항목을 클릭하는 데 사용합니다.
elementDescriptors Android UI 계층 구조를 사용하여 클릭된 UI 위젯을 식별합니다. visionText와 상호 배타적입니다.
visionText OCR을 사용하여 클릭된 요소를 식별합니다. elementDescriptors와 상호 배타적입니다.
maxNumberOfRuns eventTypeSOFT_KEYBOARD_RANDOM_CLICK일 때 소프트 키보드의 임의 요소를 클릭하는 횟수를 지정합니다. 기본값은 1입니다.

다음은 리소스 ID가 "com.google.samples.apps.topeka:id/done"인 버튼을 클릭하는 Robo 스크립트 작업의 예입니다.

{
  "eventType": "VIEW_CLICKED",
  "elementDescriptors": [
    {
      "resourceId": "com.google.samples.apps.topeka:id/done"
    }
  ]
}

다음은 OCR을 사용하여 화면에서 감지된 "Privacy Policy"를 클릭하는 Robo 스크립트 작업의 예입니다.

{
  "eventType": "VIEW_CLICKED",
  "visionText": "Privacy Policy"
}

다음은 콘텐츠 설명이 "Emoji button"인 소프트 키보드 요소를 클릭하는 Robo 스크립트 작업의 예입니다.

{
  "eventType": "SOFT_KEYBOARD_CLICK",
  "elementDescriptors": [
    {
      "contentDescription": "Emoji button"
    }
  ]
}

다음은 임의의 소프트 키보드 요소를 최대 5회 클릭하는 Robo 스크립트 작업의 예입니다.

{
  "eventType": "SOFT_KEYBOARD_RANDOM_CLICK",
  "maxNumberOfRuns": 5
}

소프트 키보드 사용 중지

다음 표에는 필수 속성이 나와 있습니다.

속성 설명
"eventType": "DISABLE_KEYBOARD" --

다음은 소프트 키보드를 사용 중지하는 Robo 스크립트 작업의 예입니다.

{
  "eventType": "DISABLE_KEYBOARD"
}

adb 셸 명령어 실행

다음 표에는 필수 속성이 나와 있습니다.

속성 설명
"eventType": "ADB_SHELL_COMMAND" --
command 실행할 Android 디버그 브리지(adb) 셸 명령어

다음은 테스트 중인 사용자 데이터를 삭제하는 Robo 스크립트 작업의 예입니다.

{
  "eventType": "ADB_SHELL_COMMAND",
  "command": "pm clear __%APP_PACKAGE_NAME%__"
}

권한 부여

이 작업은 Espresso Test Recorder의 이전 버전과 호환될 수 있도록 Android 스튜디오의 Robo 스크립트 레코더로 기록됩니다. Robo 테스트는 모든 크롤링이 시작될 때 테스트 중인 앱에 모든 권한을 부여하므로 이 작업은 노옵스(no-ops)입니다. Robo 스크립트에서 이 작업을 사용하지 마세요.

다음 표에는 필수 속성이 나와 있습니다.

속성 설명
"eventType": "PERMISSIONS_REQUEST" --

화면의 모든 요소 무시

이 작업을 통해 Robo는 포함된 Robo 스크립트를 트리거하는 모든 화면의 요소를 무시합니다.

다음 표에는 필수 속성이 나와 있습니다.

속성 설명
"eventType": "ALL_ELEMENTS_IGNORED" --

다음은 Robo에서 화면의 모든 요소를 무시하도록 하는 Robo 스크립트 작업의 예입니다.

{
  "eventType": "ALL_ELEMENTS_IGNORED"
}

요소 무시

이 작업을 수행하면 Robo가 지정된 elementDescriptors와 일치하는 요소를 무시합니다.

다음 표에는 필수 속성이 나와 있습니다.

속성 설명
"eventType": "ELEMENT_IGNORED" --
elementDescriptors Android UI 계층 구조를 사용하여 무시된 UI 위젯을 식별합니다.

다음 속성은 선택사항입니다.

  • ignoreChildren - true로 설정하면 Robo가 무시된 UI 위젯의 모든 하위 요소도 무시합니다. 기본값은 false입니다.

다음은 콘텐츠 설명이 "Avatar"로 시작하는 모든 요소를 Robo에서 무시하도록 하는 Robo 스크립트 작업의 예입니다.

{
  "eventType": "ELEMENT_IGNORED",
  "elementDescriptors": [
    {
      "contentDescriptionRegex": "Avatar.*"
    }
  ]
}

입력 텍스트

다음 표에는 필수 속성이 나와 있습니다.

속성 설명
eventType Robo 스크립트 작업의 유형을 지정합니다.
"eventType": "VIEW_TEXT_CHANGED" 대상 UI 위젯에 지정된 텍스트를 입력합니다.
"eventType": "ENTER_TEXT" 대상 UI 위젯에 지정된 텍스트를 입력한 후 이 UI 위젯에 KEYCODE_ENTER 이벤트를 전송합니다.
elementDescriptors Android UI 계층 구조를 사용하여 대상 UI 위젯을 식별합니다.
replacementText 대상 UI 위젯에 입력할 텍스트입니다.

다음은 리소스 ID가 "com.google.samples.apps.topeka:id/first_name"인 UI 위젯에 "John"을 입력하는 Robo 스크립트 작업의 예입니다.

{
  "eventType": "VIEW_TEXT_CHANGED",
  "replacementText": "John",
  "elementDescriptors": [
    {
      "resourceId": "com.google.samples.apps.topeka:id/first_name"
    }
  ]
}

길게 클릭

다음 표에는 필수 속성이 나와 있습니다.

속성 설명
"eventType": "VIEW_LONG_CLICKED" --
elementDescriptors Android UI 계층 구조를 사용하여 대상 UI 위젯을 식별합니다.

다음 속성은 선택사항입니다.

  • delayTime - 길게 클릭하는 지속 시간을 밀리초 단위로 지정합니다.

다음은 콘텐츠 설명이 "Avatar 8"인 UI 위젯을 5초간 길게 클릭하는 동작의 Robo 스크립트 예입니다.

{
  "eventType": "VIEW_LONG_CLICKED",
  "elementDescriptors": [
    {
      "contentDescription": "Avatar 8"
    }
  ],
  "delayTime": 5000
}

한 지점 동작 실행

다음 표에는 필수 속성이 나와 있습니다.

속성 설명
"eventType": "ONE_POINT_GESTURE" --
coordinates 백분율 또는 픽셀로 표시된 '(x1,y1)->(x2,y2)' 형식의 한 지점 동작에 대한 2개의 좌표입니다.

다음 속성은 선택사항입니다.

  • dragAndDrop - true로 설정된 경우 한 포인트 동작은 드래그 앤 드롭 작업을 실행합니다. 기본값은 false입니다.

다음은 아래로 스와이프하는 Robo 스크립트 한 지점 동작 작업의 예입니다.

{
  "eventType": "ONE_POINT_GESTURE",
  "coordinates": "(50%,25%)->(50%,75%)"
}

두 지점 동작 실행

다음 표에는 필수 속성이 나와 있습니다.

속성 설명
"eventType": "TWO_POINT_GESTURE" --
coordinates 백분율 또는 픽셀로 표시된 '(x1,y1)->(x2,y2),(x3,y3)->(x4,y4)' 형식의 두 지점 동작에 대한 4개의 좌표입니다.

다음은 손가락 벌리기 동작을 실행하는 Robo 스크립트 작업의 예입니다.

{
  "eventType": "TWO_POINT_GESTURE",
  "coordinates": "(50%,50%)->(25%,50%),(50%,50%)->(75%,50%)"
}

IME 작업 실행

이 작업은 지정된 대상 UI 위젯의 입력 방식 편집기(IME)에서 현재 작업 버튼(예: 다음 작업, 완료, 검색)을 누릅니다.

다음 표에는 필수 속성이 나와 있습니다.

속성 설명
"eventType": "PRESSED_EDITOR_ACTION" --
elementDescriptors Android UI 계층 구조를 사용하여 대상 UI 위젯을 식별합니다.

다음은 리소스 ID가 "com.google.samples.apps.topeka:id/first_name"인 UI 위젯에서 IME 작업을 실행하는 Robo 스크립트 작업의 예입니다.

{
  "eventType": "PRESSED_EDITOR_ACTION",
  "elementDescriptors": [
    {
      "resourceId": "com.google.samples.apps.topeka:id/first_name"
    }
  ]
}

뒤로 버튼 누름

다음 표에는 필수 속성이 나와 있습니다.

속성 설명
eventType Robo 스크립트 작업의 유형을 지정합니다.
"eventType": "PRESSED_BACK" KEYCODE_BACK 이벤트를 기기로 전송합니다.
"eventType": "PRESSED_BACK_EMULATOR_28" 에뮬레이터 API 28에서 뒤로 버튼을 누를 수 있도록 Android 스튜디오의 Robo 스크립트 레코더에서 사용합니다.

다음은 뒤로 버튼을 누르는 Robo 스크립트 작업의 예입니다.

{
  "eventType": "PRESSED_BACK"
}

홈 버튼 누름

이 작업은 기기로 KEYCODE_HOME 이벤트를 전송합니다.

다음 표에는 필수 속성이 나와 있습니다.

속성 설명
"eventType": "GO_HOME" --

다음은 홈 버튼을 누르는 Robo 스크립트 작업의 예입니다.

{
  "eventType": "GO_HOME"
}

요소를 뷰로 스크롤

이 작업은 지정된 childElementDescriptors와 일치하는 UI 위젯이 화면에 표시되거나 스크롤된 위젯을 더 이상 스크롤할 수 없거나 최대 스크롤 수 50개에 도달할 때까지 Robo 테스트가 지정된 elementDescriptors와 일치하는 UI 위젯을 앞으로 스크롤하게 합니다.

다음 표에는 필수 속성이 나와 있습니다.

속성 설명
"eventType": "ELEMENT_SCROLL_INTO_VIEW" --
elementDescriptors Android UI 계층 구조를 사용하여 스크롤된 UI 위젯을 식별합니다.
childElementDescriptors Android UI 계층 구조를 사용하여 스크롤할 UI 위젯을 식별합니다.

다음은 "Orange" 텍스트가 포함된 UI 위젯이 화면에 표시되거나 더 이상 스크롤할 수 없거나 최대 스크롤 수 50개에 도달할 때까지 리소스 ID가 "my.app.package:id/scrollable_card_container"인 UI 위젯을 스크롤하는 Robo 스크립트 작업의 예입니다.

{
  "eventType": "ELEMENT_SCROLL_INTO_VIEW",
  "elementDescriptors": [
    {
      "resourceId": "my.app.package:id/scrollable_card_container"
    }
  ],
  "childElementDescriptors": [
    {
      "text": "Orange"
    }
  ]
}

스와이프

다음 표에는 필수 속성이 나와 있습니다.

속성 설명
"eventType": "VIEW_SWIPED" --
swipeDirection 스와이프 방향을 지정합니다.
  • Left
  • Right
  • Up
  • Down
  • Forward - 대상 UI 위젯의 세로 또는 가로 스크롤 가능 여부에 따라 Down 또는 Right입니다.
  • Backward - 대상 UI 위젯의 세로 또는 가로 스크롤 가능 여부에 따라 Up 또는 Left입니다.
elementDescriptors Android UI 계층 구조를 사용하여 대상 UI 위젯을 식별합니다.

다음은 리소스 ID가 "my.app.package:id/custom_content"인 UI 위젯을 위로 스와이프하는 Robo 스크립트 작업의 예입니다.

{
  "eventType": "VIEW_SWIPED",
  "swipeDirection": "Up",
  "elementDescriptors": [
    {
      "resourceId": "my.app.package:id/custom_content"
    }
  ]
}

스크린샷 찍기

다음 표에는 필수 속성이 나와 있습니다.

속성 설명
"eventType": "TAKE_SCREENSHOT" --
screenshotName 스크린샷 파일 이름을 지정합니다.

다음은 스크린샷을 찍는 Robo 스크립트 작업의 예입니다.

{
  "eventType": "TAKE_SCREENSHOT",
  "screenshotName": "my_screenshot"
}

화면의 한 지점을 탭합니다.

다음 표에는 필수 속성이 나와 있습니다.

속성 설명
"eventType": "POINT_TAP" --
pointTapXCoordinate 탭한 지점의 픽셀 X 좌표입니다. pointTapXPercentpointTapYPercent와 상호 배타적입니다.
pointTapYCoordinate 탭한 지점의 픽셀 Y 좌표입니다. pointTapXPercentpointTapYPercent와 상호 배타적입니다.
pointTapXPercent 탭한 지점의 백분율 X 좌표입니다. pointTapXCoordinatepointTapYCoordinate와 상호 배타적입니다.
pointTapYPercent 탭한 지점의 백분율 Y 좌표입니다. pointTapXCoordinatepointTapYCoordinate와 상호 배타적입니다.

다음은 화면 중앙에서 탭하는 Robo 스크립트 작업의 예입니다.

{
  "eventType": "POINT_TAP",
  "pointTapXPercent": 50,
  "pointTapYPercent": 50
}

요소 내의 한 지점 탭하기

다음 표에는 필수 속성이 나와 있습니다.

속성 설명
"eventType": "POINT_TAP_ELEMENT" --
pointTapXPercent 대상 요소 내의 백분율 X 좌표입니다.
pointTapYPercent 대상 요소 내의 백분율 Y 좌표입니다.
elementDescriptors Android UI 계층 구조를 사용하여 대상 UI 위젯을 식별합니다.

다음은 탐색 메뉴의 슬라이더를 오른쪽으로 이동하는 Robo 스크립트 작업의 예입니다.

{
  "eventType": "POINT_TAP_ELEMENT",
  "pointTapXPercent": 80,
  "pointTapYPercent": 50,
  "elementDescriptors": [
    {
      "resourceId": "my.app.package:id/my_seekbar"
    }
  ]
}

크롤링 종료

이렇게 하면 Robo 테스트가 중지됩니다.

다음 표에는 필수 속성이 나와 있습니다.

속성 설명
"eventType": "TERMINATE_CRAWL" --

다음은 Robo 테스트를 중지하는 Robo 스크립트 작업의 예입니다.

{
  "eventType": "TERMINATE_CRAWL"
}

대기

다음 표에는 필수 속성이 나와 있습니다.

속성 설명
"eventType": "DELAYED_MESSAGE_POSTED" --
delayTime 대기 시간(밀리초)을 지정합니다.

다음은 3초 동안 기다리는 Robo 스크립트 작업의 예입니다.

{
  "eventType": "DELAYED_MESSAGE_POSTED",
  "delayTime": 3000
}

요소 대기

이렇게 하면 Robo 테스트에서 요소가 화면에 표시될 때까지 지정된 제한 시간 동안 기다립니다.

다음 표에는 필수 속성이 나와 있습니다.

속성 설명
"eventType": "WAIT_FOR_ELEMENT" --
delayTime 대기 제한 시간(밀리초)을 지정합니다.
elementDescriptors Android UI 계층 구조를 사용하여 대기 중인 UI 위젯을 식별합니다.

다음은 리소스 ID가 "my.app.package:id/confirmation_button"인 UI 위젯이 화면에 표시될 때까지 최대 30초 동안 기다리는 Robo 스크립트 작업의 예입니다.

{
  "eventType": "WAIT_FOR_ELEMENT",
  "delayTime": 30000,
  "elementDescriptors": [
    {
      "resourceId": "my.app.package:id/confirmation_button"
    }
  ]
}

다음 단계