UI Automator를 사용하여 자동화된 테스트 작성

UI Automator는 시스템과 설치된 앱 전반에서 앱 간 기능적 UI 테스트에 적합한 UI 테스트 프레임워크입니다. UI Automator API를 사용하면 포커스가 있는 Activity와 관계없이 기기에 표시되는 요소와 상호작용할 수 있으므로 테스트 기기에서 설정 메뉴나 앱 런처 열기와 같은 작업을 실행할 수 있습니다. 테스트는 구성요소에 표시된 텍스트나 콘텐츠 설명과 같은 편리한 설명어를 사용하여 UI 구성요소를 찾을 수 있습니다.

UI Automator 테스트 프레임워크는 계측 기반 API이며 AndroidJUnitRunner 테스트 실행기와 함께 작동합니다. 이는 테스트 코드가 타겟 앱의 내부 구현 세부정보에 의존하지 않는 불투명 상자 스타일의 자동 테스트를 작성하는 데 매우 적합합니다.

UI Automator 테스트 프레임워크의 주요 기능에는 다음이 포함됩니다.

  • 대상 기기에서 상태 정보를 검색하고 작업을 실행하는 API 자세한 내용은 기기 상태 액세스를 참고하세요.
  • 앱 간의 UI 테스트를 지원하는 API. 자세한 내용은 UI Automator API를 참고하세요.

기기 상태 액세스

UI Automator 테스트 프레임워크는 타겟 앱이 실행되는 기기에 액세스하여 작업을 실행하기 위한 UiDevice 클래스를 제공합니다. 이 객체의 메서드를 호출하여 현재 방향이나 디스플레이 크기와 같은 기기 속성에 액세스할 수 있습니다. UiDevice 클래스를 사용하면 다음 작업도 실행할 수 있습니다.

  1. 기기 회전 변경
  2. '볼륨 업'과 같은 하드웨어 키를 누릅니다.
  3. 뒤로 버튼, 홈 버튼 또는 메뉴 버튼 누르기
  4. 알림 창 열기
  5. 현재 창의 스크린샷 찍기

예를 들어 홈 버튼 누르기를 시뮬레이션하려면 UiDevice.pressHome() 메서드를 호출합니다.

UI Automator API

UI Automator API를 사용하면 타겟팅하는 앱의 구현 세부정보를 몰라도 강력한 테스트를 작성할 수 있습니다. 다음과 같은 API를 사용하여 여러 앱에서 UI 구성요소를 캡처하고 조작할 수 있습니다.

  • UiObject2: 기기에 표시되는 UI 요소를 나타냅니다.
  • BySelector: 일치하는 UI 요소의 기준을 지정합니다.
  • By: 간결한 방식으로 BySelector를 구성합니다.
  • Configurator: UI Automator 테스트를 실행하기 위한 주요 매개변수를 설정할 수 있습니다.

예를 들어 다음 코드는 기기에서 Gmail 앱을 여는 테스트 스크립트를 작성하는 방법을 보여줍니다.

Kotlin


device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
device.pressHome()

val gmail: UiObject2 = device.findObject(By.text("Gmail"))
// Perform a click and wait until the app is opened.
val opened: Boolean = gmail.clickAndWait(Until.newWindow(), 3000)
assertThat(opened).isTrue()

Java


device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
device.pressHome();

UiObject2 gmail = device.findObject(By.text("Gmail"));
// Perform a click and wait until the app is opened.
Boolean opened = gmail.clickAndWait(Until.newWindow(), 3000);
assertTrue(opened);

UI Automator 설정

UI Automator를 사용하여 UI 테스트를 빌드하기 전에 AndroidX 테스트용 프로젝트 설정에 설명된 대로 테스트 소스 코드 위치 및 프로젝트 종속 항목을 구성해야 합니다.

Android 앱 모듈의 build.gradle 파일에서 UI Automator 라이브러리의 종속 항목 참조를 설정해야 합니다.

Kotlin

dependencies {
  ...
  androidTestImplementation('androidx.test.uiautomator:uiautomator:2.3.0-alpha03')
}

Groovy

dependencies {
  ...
  androidTestImplementation 'androidx.test.uiautomator:uiautomator:2.3.0-alpha03'
}

UI Automator 테스트를 최적화하려면 먼저 타겟 앱의 UI 구성요소를 검사하고 액세스할 수 있는지 확인해야 합니다. 이러한 최적화 도움말은 다음 두 섹션에서 설명합니다.

기기의 UI 검사

테스트를 설계하기 전에 기기에 표시되는 UI 구성요소를 검사합니다. UI Automator 테스트에서 이러한 구성요소에 액세스할 수 있는지 확인하려면 이러한 구성요소에 표시되는 텍스트 라벨이나 android:contentDescription 값 또는 둘 다 있는지 확인합니다.

uiautomatorviewer 도구는 레이아웃 계층 구조를 검사하고 기기의 포그라운드에 표시되는 UI 구성요소의 속성을 볼 수 있는 편리한 시각적 인터페이스를 제공합니다. 이 정보를 통해 UI Automator를 사용하여 더 세분화된 테스트를 만들 수 있습니다. 예를 들어 표시되는 특정 속성과 일치하는 UI 선택기를 만들 수 있습니다.

uiautomatorviewer 도구를 실행하려면 다음 단계를 따르세요.

  1. 실제 기기에서 타겟 앱을 실행합니다.
  2. 기기를 개발 머신에 연결합니다.
  3. 터미널 창을 열고 <android-sdk>/tools/ 디렉터리로 이동합니다.
  4. 다음 명령어를 사용하여 도구를 실행합니다.
 $ uiautomatorviewer

애플리케이션의 UI 속성을 보려면 다음 단계를 따르세요.

  1. uiautomatorviewer 인터페이스에서 Device Screenshot 버튼을 클릭합니다.
  2. 왼쪽 패널에 있는 스냅샷 위로 마우스를 가져가서 uiautomatorviewer 도구로 식별된 UI 구성요소를 확인합니다. 속성은 오른쪽 하단 패널에 나열되고 레이아웃 계층 구조는 오른쪽 상단 패널에 나열됩니다.
  3. 선택적으로 Toggle NAF Nodes 버튼을 클릭하여 UI Automator에 액세스할 수 없는 UI 구성요소를 확인합니다. 이러한 구성요소에는 제한된 정보만 사용할 수 있습니다.

Android에서 제공하는 일반적인 UI 구성요소 유형에 관해 알아보려면 사용자 인터페이스를 참고하세요.

활동의 접근성 확인

UI Automator 테스트 프레임워크는 Android 접근성 기능을 구현한 앱에서 더 나은 성능을 발휘합니다. View 유형의 UI 요소 또는 SDK에서 View의 서브클래스를 사용하는 경우 접근성 지원을 구현할 필요가 없습니다. 이러한 클래스에 접근성 지원이 이미 구현되어 있기 때문입니다.

그러나 일부 앱에서는 맞춤 UI 요소를 사용하여 보다 풍부한 사용자 환경을 제공합니다. 이러한 요소는 자동 접근성 지원을 제공하지 않습니다. SDK에서 제공하지 않은 View의 서브클래스 인스턴스가 앱에 포함되어 있다면 다음 단계를 완료하여 이러한 요소에 접근성 기능을 추가해야 합니다.

  1. ExploreByTouchHelper를 확장하는 구체적인 클래스를 만듭니다.
  2. setAccessibilityDelegate()를 호출하여 새 클래스의 인스턴스를 특정 맞춤 UI 요소와 연결합니다.

맞춤 뷰 요소에 접근성 기능을 추가하는 방법에 관한 자세한 내용은 액세스 가능한 맞춤 뷰 빌드를 참고하세요. Android의 접근성에 관한 일반적인 권장사항을 자세히 알아보려면 더욱 접근성 높은 앱 만들기를 참고하세요.

UI Automator 테스트 클래스 만들기

UI Automator 테스트 클래스는 JUnit 4 테스트 클래스와 동일한 방식으로 작성해야 합니다. JUnit 4 테스트 클래스를 만드는 방법과 JUnit 4 어설션 및 주석을 사용하는 방법을 자세히 알아보려면 계측 단위 테스트 클래스 만들기를 참고하세요.

테스트 클래스 정의의 시작 부분에 @RunWith(AndroidJUnit4.class) 주석을 추가합니다. 또한 AndroidX 테스트에서 제공된 AndroidJUnitRunner 클래스를 기본 테스트 실행기로 지정해야 합니다. 이 단계는 기기 또는 에뮬레이터에서 UI Automator 테스트 실행에 자세히 설명되어 있습니다.

UI Automator 테스트 클래스에서 다음 프로그래밍 모델을 구현하세요.

  1. getInstance() 메서드를 호출하고 Instrumentation 객체를 인수로 전달하여 테스트할 기기에 액세스할 UiDevice 객체를 가져옵니다.
  2. findObject() 메서드를 호출하여 기기에 표시되는 UI 구성요소(예: 포그라운드의 현재 뷰)에 액세스하기 위한 UiObject2 객체를 가져옵니다.
  3. UiObject2 메서드를 호출하여 UI 구성요소에서 실행할 특정 사용자 상호작용을 시뮬레이션합니다. 예를 들어 scrollUntil()을 호출하여 스크롤하고 setText()를 호출하여 텍스트 필드를 수정합니다. 필요에 따라 2단계와 3단계의 API를 반복적으로 호출하여 여러 UI 구성요소 또는 사용자 작업 시퀀스와 관련된 더 복잡한 사용자 상호작용을 테스트할 수 있습니다.
  4. 이러한 사용자 상호작용이 실행된 후 UI에 예상 상태 또는 동작이 반영되었는지 확인합니다.

아래 섹션에서 이러한 단계를 더 자세히 다룹니다.

UI 구성요소에 액세스

UiDevice 객체는 기기 상태에 액세스하고 이를 조작하는 기본적인 방법입니다. 테스트에서 UiDevice 메서드를 호출하여 현재 방향이나 디스플레이 크기와 같은 다양한 속성의 상태를 확인할 수 있습니다. 테스트에서 UiDevice 객체를 사용하여 기기를 특정 회전으로 강제 설정, D패드 하드웨어 버튼 누르기, 홈 및 메뉴 버튼 누르기와 같은 기기 수준 작업을 실행할 수 있습니다.

기기의 홈 화면에서 테스트를 시작하는 것이 좋습니다. 홈 화면 (또는 기기에서 선택한 다른 시작 위치)에서 UI Automator API에서 제공하는 메서드를 호출하여 특정 UI 요소를 선택하고 상호작용할 수 있습니다.

다음 코드 스니펫은 테스트에서 UiDevice의 인스턴스를 가져오고 홈 버튼 누르기를 시뮬레이션하는 방법을 보여줍니다.

Kotlin


import org.junit.Before
import androidx.test.runner.AndroidJUnit4
import androidx.test.uiautomator.UiDevice
import androidx.test.uiautomator.By
import androidx.test.uiautomator.Until
...

private const val BASIC_SAMPLE_PACKAGE = "com.example.android.testing.uiautomator.BasicSample"
private const val LAUNCH_TIMEOUT = 5000L
private const val STRING_TO_BE_TYPED = "UiAutomator"

@RunWith(AndroidJUnit4::class)
@SdkSuppress(minSdkVersion = 18)
class ChangeTextBehaviorTest2 {

private lateinit var device: UiDevice

@Before
fun startMainActivityFromHomeScreen() {
  // Initialize UiDevice instance
  device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())

  // Start from the home screen
  device.pressHome()

  // Wait for launcher
  val launcherPackage: String = device.launcherPackageName
  assertThat(launcherPackage, notNullValue())
  device.wait(
    Until.hasObject(By.pkg(launcherPackage).depth(0)),
    LAUNCH_TIMEOUT
  )

  // Launch the app
  val context = ApplicationProvider.getApplicationContext<Context>()
  val intent = context.packageManager.getLaunchIntentForPackage(
  BASIC_SAMPLE_PACKAGE).apply {
    // Clear out any previous instances
    addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK)
  }
  context.startActivity(intent)

  // Wait for the app to appear
  device.wait(
    Until.hasObject(By.pkg(BASIC_SAMPLE_PACKAGE).depth(0)),
    LAUNCH_TIMEOUT
    )
  }
}

Java


import org.junit.Before;
import androidx.test.runner.AndroidJUnit4;
import androidx.test.uiautomator.UiDevice;
import androidx.test.uiautomator.By;
import androidx.test.uiautomator.Until;
...

@RunWith(AndroidJUnit4.class)
@SdkSuppress(minSdkVersion = 18)
public class ChangeTextBehaviorTest {

  private static final String BASIC_SAMPLE_PACKAGE
  = "com.example.android.testing.uiautomator.BasicSample";
  private static final int LAUNCH_TIMEOUT = 5000;
  private static final String STRING_TO_BE_TYPED = "UiAutomator";
  private UiDevice device;

  @Before
  public void startMainActivityFromHomeScreen() {
    // Initialize UiDevice instance
    device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());

    // Start from the home screen
    device.pressHome();

    // Wait for launcher
    final String launcherPackage = device.getLauncherPackageName();
    assertThat(launcherPackage, notNullValue());
    device.wait(Until.hasObject(By.pkg(launcherPackage).depth(0)),
    LAUNCH_TIMEOUT);

    // Launch the app
    Context context = ApplicationProvider.getApplicationContext();
    final Intent intent = context.getPackageManager()
    .getLaunchIntentForPackage(BASIC_SAMPLE_PACKAGE);
    // Clear out any previous instances
    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
    context.startActivity(intent);

    // Wait for the app to appear
    device.wait(Until.hasObject(By.pkg(BASIC_SAMPLE_PACKAGE).depth(0)),
    LAUNCH_TIMEOUT);
    }
}

이 예에서 @SdkSuppress(minSdkVersion = 18) 문은 UI Automator 프레임워크에서 요구하는 대로 테스트가 Android 4.3 (API 수준 18) 이상이 설치된 기기에서만 실행되도록 하는 데 도움이 됩니다.

findObject() 메서드를 사용하여 지정된 선택기 기준과 일치하는 뷰를 나타내는 UiObject2를 검색합니다. 필요한 경우 앱 테스트의 다른 부분에서 만든 UiObject2 인스턴스를 재사용할 수 있습니다. UI Automator 테스트 프레임워크는 테스트에서 UiObject2 인스턴스를 사용하여 UI 요소를 클릭하거나 속성을 쿼리할 때마다 현재 디스플레이에서 일치 항목을 검색합니다.

다음 스니펫은 테스트가 앱에서 취소 버튼과 확인 버튼을 나타내는 UiObject2 인스턴스를 구성하는 방법을 보여줍니다.

Kotlin


val okButton: UiObject2 = device.findObject(
    By.text("OK").clazz("android.widget.Button")
)

// Simulate a user-click on the OK button, if found.
if (okButton != null) {
    okButton.click()
}

Java


UiObject2 okButton = device.findObject(
    By.text("OK").clazz("android.widget.Button")
);

// Simulate a user-click on the OK button, if found.
if (okButton != null) {
    okButton.click();
}

선택기 지정

앱의 특정 UI 구성요소에 액세스하려면 By 클래스를 사용하여 BySelector 인스턴스를 구성합니다. BySelector는 표시된 UI의 특정 요소에 관한 쿼리를 나타냅니다.

일치하는 요소가 두 개 이상 발견되면 레이아웃 계층 구조에서 일치하는 첫 번째 요소가 타겟 UiObject2로 반환됩니다. BySelector를 구성할 때 여러 속성을 함께 연결하여 검색 범위를 좁힐 수 있습니다. 일치하는 UI 요소가 없으면 null이 반환됩니다.

hasChild() 또는 hasDescendant() 메서드를 사용하여 여러 BySelector 인스턴스를 중첩할 수 있습니다. 예를 들어 다음 코드 예는 테스트에서 검색을 지정하여 텍스트 속성이 있는 하위 UI 요소가 있는 첫 번째 ListView를 찾는 방법을 보여줍니다.

Kotlin


val listView: UiObject2 = device.findObject(
    By.clazz("android.widget.ListView")
        .hasChild(
            By.text("Apps")
        )
)

Java


UiObject2 listView = device.findObject(
    By.clazz("android.widget.ListView")
        .hasChild(
            By.text("Apps")
        )
);

선택기 기준에서 객체 상태를 지정하는 것이 유용할 수 있습니다. 예를 들어 선택한 모든 요소의 목록을 선택 해제하여 선택하려면 인수를 true로 설정하여 checked() 메서드를 호출합니다.

작업 실행

테스트에서 UiObject2 객체를 가져오고 나면 UiObject2 클래스의 메서드를 호출하여 이 객체가 나타내는 UI 구성요소에서 사용자 상호작용을 실행할 수 있습니다. 다음과 같은 작업을 지정할 수 있습니다.

  • click() : UI 요소에 표시된 경계의 중심을 클릭합니다.
  • drag() : 이 객체를 임의의 좌표로 드래그합니다.
  • setText() : 필드의 콘텐츠를 지운 후 수정 가능한 필드에 텍스트를 설정합니다. 반대로 clear() 메서드는 수정 가능한 필드에서 기존 텍스트를 지웁니다.
  • swipe() : 지정된 방향으로 스와이프 작업을 실행합니다.
  • scrollUntil(): Condition 또는 EventCondition가 충족될 때까지 지정된 방향으로 스크롤 작업을 실행합니다.

UI Automator 테스트 프레임워크를 사용하면 getContext()를 통해 Context 객체를 가져와 셸 명령어를 사용하지 않고 Intent를 전송하거나 Activity를 실행할 수 있습니다.

다음 스니펫은 테스트에서 Intent를 사용하여 테스트 중인 앱을 실행하는 방법을 보여줍니다. 이 접근 방식은 계산기 앱 테스트에만 관심이 있고 런처에는 관심이 없는 경우에 유용합니다.

Kotlin


fun setUp() {
...

  // Launch a simple calculator app
  val context = getInstrumentation().context
  val intent = context.packageManager.getLaunchIntentForPackage(CALC_PACKAGE).apply {
    addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK)
  }
  // Clear out any previous instances
  context.startActivity(intent)
  device.wait(Until.hasObject(By.pkg(CALC_PACKAGE).depth(0)), TIMEOUT)
}

Java


public void setUp() {
...

  // Launch a simple calculator app
  Context context = getInstrumentation().getContext();
  Intent intent = context.getPackageManager()
  .getLaunchIntentForPackage(CALC_PACKAGE);
  intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);

  // Clear out any previous instances
  context.startActivity(intent);
  device.wait(Until.hasObject(By.pkg(CALC_PACKAGE).depth(0)), TIMEOUT);
}

결과 확인

InstrumentationTestCaseTestCase를 확장하므로 표준 JUnit Assert 메서드를 사용하여 앱의 UI 구성요소가 예상 결과를 반환하는지 테스트할 수 있습니다.

다음 스니펫은 테스트가 계산기 앱에서 여러 버튼을 찾아 순서대로 클릭한 다음 올바른 결과가 표시되는지 확인하는 방법을 보여줍니다.

Kotlin


private const val CALC_PACKAGE = "com.myexample.calc"

fun testTwoPlusThreeEqualsFive() {
  // Enter an equation: 2 + 3 = ?
  device.findObject(By.res(CALC_PACKAGE, "two")).click()
  device.findObject(By.res(CALC_PACKAGE, "plus")).click()
  device.findObject(By.res(CALC_PACKAGE, "three")).click()
  device.findObject(By.res(CALC_PACKAGE, "equals")).click()

  // Verify the result = 5
  val result: UiObject2 = device.findObject(By.res(CALC_PACKAGE, "result"))
  assertEquals("5", result.text)
}

Java


private static final String CALC_PACKAGE = "com.myexample.calc";

public void testTwoPlusThreeEqualsFive() {
  // Enter an equation: 2 + 3 = ?
  device.findObject(By.res(CALC_PACKAGE, "two")).click();
  device.findObject(By.res(CALC_PACKAGE, "plus")).click();
  device.findObject(By.res(CALC_PACKAGE, "three")).click();
  device.findObject(By.res(CALC_PACKAGE, "equals")).click();

  // Verify the result = 5
  UiObject2 result = device.findObject(By.res(CALC_PACKAGE, "result"));
  assertEquals("5", result.getText());
}

기기 또는 에뮬레이터에서 UI Automator 테스트 실행

Android 스튜디오 또는 명령줄에서 UI Automator 테스트를 실행할 수 있습니다. AndroidJUnitRunner를 프로젝트의 기본 계측 실행기로 지정해야 합니다.

사례 더보기

시스템 UI와 상호작용

UI Automator는 다음 코드 스니펫과 같이 앱 외부의 시스템 요소를 비롯하여 화면의 모든 항목과 상호작용할 수 있습니다.

Kotlin


// Opens the System Settings.
device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
device.executeShellCommand("am start -a android.settings.SETTINGS")

Java


// Opens the System Settings.
device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
device.executeShellCommand("am start -a android.settings.SETTINGS");

Kotlin


// Opens the notification shade.
device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
device.openNotification()

Java


// Opens the notification shade.
device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
device.openNotification();

Kotlin


// Opens the Quick Settings shade.
device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
device.openQuickSettings()

Java


// Opens the Quick Settings shade.
device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
device.openQuickSettings();

Kotlin


// Get the system clock.
device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
UiObject2 clock = device.findObject(By.res("com.android.systemui:id/clock"))
print(clock.getText())

Java


// Get the system clock.
device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
UiObject2 clock = device.findObject(By.res("com.android.systemui:id/clock"));
print(clock.getText());

전환 대기

방해 금지
그림 1. UI Automator가 테스트 기기에서 방해 금지 모드를 사용 중지합니다.

화면 전환은 시간이 걸릴 수 있고 전환 시간을 신뢰할 수 없을 것으로 예상할 수 있으므로 작업 실행 후 UI Automator가 대기하도록 해야 합니다. UI Automator는 이를 위한 여러 메서드를 제공합니다.

다음 코드 스니펫은 UI Automator를 사용하여 전환을 기다리는 performActionAndWait() 메서드로 시스템 설정에서 방해 금지 모드를 사용 중지하는 방법을 보여줍니다.

Kotlin


@Test
@SdkSuppress(minSdkVersion = 21)
@Throws(Exception::class)
fun turnOffDoNotDisturb() {
    device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
    device.performActionAndWait({
        try {
            device.executeShellCommand("am start -a android.settings.SETTINGS")
        } catch (e: IOException) {
            throw RuntimeException(e)
        }
    }, Until.newWindow(), 1000)
    // Check system settings has been opened.
    Assert.assertTrue(device.hasObject(By.pkg("com.android.settings")))

    // Scroll the settings to the top and find Notifications button
    var scrollableObj: UiObject2 = device.findObject(By.scrollable(true))
    scrollableObj.scrollUntil(Direction.UP, Until.scrollFinished(Direction.UP))
    val notificationsButton = scrollableObj.findObject(By.text("Notifications"))

    // Click the Notifications button and wait until a new window is opened.
    device.performActionAndWait({ notificationsButton.click() }, Until.newWindow(), 1000)
    scrollableObj = device.findObject(By.scrollable(true))
    // Scroll down until it finds a Do Not Disturb button.
    val doNotDisturb = scrollableObj.scrollUntil(
        Direction.DOWN,
        Until.findObject(By.textContains("Do Not Disturb"))
    )
    device.performActionAndWait({ doNotDisturb.click() }, Until.newWindow(), 1000)
    // Turn off the Do Not Disturb.
    val turnOnDoNotDisturb = device.findObject(By.text("Turn on now"))
    turnOnDoNotDisturb?.click()
    Assert.assertTrue(device.wait(Until.hasObject(By.text("Turn off now")), 1000))
}

Java


@Test
@SdkSuppress(minSdkVersion = 21)
public void turnOffDoNotDisturb() throws Exception{
    device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
    device.performActionAndWait(() -> {
        try {
            device.executeShellCommand("am start -a android.settings.SETTINGS");
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }, Until.newWindow(), 1000);
    // Check system settings has been opened.
    assertTrue(device.hasObject(By.pkg("com.android.settings")));

    // Scroll the settings to the top and find Notifications button
    UiObject2 scrollableObj = device.findObject(By.scrollable(true));
    scrollableObj.scrollUntil(Direction.UP, Until.scrollFinished(Direction.UP));
    UiObject2 notificationsButton = scrollableObj.findObject(By.text("Notifications"));

    // Click the Notifications button and wait until a new window is opened.
    device.performActionAndWait(() -> notificationsButton.click(), Until.newWindow(), 1000);
    scrollableObj = device.findObject(By.scrollable(true));
    // Scroll down until it finds a Do Not Disturb button.
    UiObject2 doNotDisturb = scrollableObj.scrollUntil(Direction.DOWN,
            Until.findObject(By.textContains("Do Not Disturb")));
    device.performActionAndWait(()-> doNotDisturb.click(), Until.newWindow(), 1000);
    // Turn off the Do Not Disturb.
    UiObject2 turnOnDoNotDisturb = device.findObject(By.text("Turn on now"));
    if(turnOnDoNotDisturb != null) {
        turnOnDoNotDisturb.click();
    }
    assertTrue(device.wait(Until.hasObject(By.text("Turn off now")), 1000));
}

추가 리소스

Android 테스트에서 UI Automator를 사용하는 방법에 관한 자세한 내용은 다음 리소스를 참고하세요.

참조 문서

샘플