Google은 흑인 공동체를 위한 인종 간 평등을 진전시키기 위해 노력하고 있습니다. Google에서 어떤 노력을 하고 있는지 확인하세요.

앱 활동 테스트

활동은 앱 내 모든 사용자 상호작용의 컨테이너 역할을 하므로 다음과 같은 기기 수준 이벤트가 발생하는 동안 앱의 활동이 어떻게 동작하는지 테스트하는 것이 중요합니다.

  • 기기의 스마트폰 앱과 같은 다른 앱이 앱의 활동을 중단시킵니다.
  • 시스템이 활동을 제거하고 다시 생성합니다.
  • 사용자가 PIP 모드 또는 멀티 윈도우와 같은 새로운 윈도우 처리 환경에 활동을 배치합니다.

특히 활동이 활동 수명 주기 이해에 설명된 이벤트에 응답하여 올바르게 동작하는지 확인하는 것이 중요합니다.

이 가이드에서는 앱의 활동이 수명 주기의 다양한 상태를 통해 전환될 때 앱이 데이터 무결성 및 우수한 사용자 환경을 유지하는 기능을 평가하는 방법을 설명합니다.

활동 상태 변경

앱 활동 테스트의 한 가지 주요 측면은 앱 활동을 특정 상태에 배치하는 것입니다. 테스트의 이 '특정' 요소를 정의하려면 AndroidX 테스트 라이브러리의 일부인 ActivityScenario 인스턴스를 사용하세요. 이 클래스를 사용하면 이 페이지의 시작 부분에 설명된 기기 수준 이벤트를 시뮬레이션하는 상태에 활동을 배치할 수 있습니다.

ActivityScenario는 로컬 단위 테스트 및 기기 내 통합 테스트에서 모두 똑같이 사용할 수 있는 크로스 플랫폼 API입니다. 실제 또는 가상 기기에서 ActivityScenario는 스레드 안전성을 제공하여 테스트의 계측 스레드와 테스트 중인 활동을 실행하는 스레드 간에 이벤트를 동기화합니다. 또한 이 API는 테스트 중인 활동이 제거되거나 생성될 때 어떻게 동작하는지 평가하는 데 특히 적합합니다.

이 섹션에서는 이 API와 관련된 가장 일반적인 사용 사례를 제시합니다.

활동 생성

테스트에 사용되는 활동을 생성하려면 다음 스니펫에 나와 있는 코드를 추가합니다.

    @RunWith(AndroidJUnit4::class)
    class MyTestSuite {
        @Test fun testEvent() {
            val scenario = launchActivity<MyActivity>()
        }
    }
    

활동을 생성한 후 ActivityScenario는 활동을 RESUMED 상태로 전환합니다. 이 상태는 활동이 실행 중이며 사용자에게 표시됨을 나타냅니다. 이 상태에서는 Espresso UI 테스트를 사용하여 활동의 View 요소와 자유롭게 상호작용할 수 있습니다.

또는 ActivityScenarioRule을 사용하여 각 테스트 전에는 ActivityScenario.launch를, 테스트 해제 시에는 ActivityScenario.close를 자동으로 호출할 수 있습니다. 아래 예는 규칙을 정의하고 규칙에서 시나리오 인스턴스를 얻는 방법을 보여줍니다.

    @RunWith(AndroidJUnit4::class)
    class MyTestSuite {
        @get:Rule var activityScenarioRule = activityScenarioRule<MyActivity>()

        @Test fun testEvent() {
            val scenario = activityScenarioRule.scenario
        }
    }
    

새로운 상태로 활동 변경

활동을 CREATED 또는 STARTED와 같은 다른 상태로 변경하려면 moveToState()를 호출하세요. 이 작업은 활동이 또 다른 앱이나 시스템 작업에 의해 중단되기 때문에 각각 중지되거나 일시중지된 상황을 시뮬레이션합니다.

moveToState()의 사용 예는 다음 코드 스니펫에 나와 있습니다.

    @RunWith(AndroidJUnit4::class)
    class MyTestSuite {
        @Test fun testEvent() {
            val scenario = launchActivity<MyActivity>()
            scenario.moveToState(State.CREATED)
        }
    }
    

현재 활동 상태 확인

테스트 중인 활동의 현재 상태를 확인하려면 ActivityScenario 객체 내의 state 필드 값을 가져와야 합니다. 다음 코드 스니펫에서와 같이 활동이 또 다른 활동으로 리디렉션되거나 자체적으로 완료될 때 테스트 중인 활동의 상태를 확인하는 것은 특히 도움이 됩니다.

    @RunWith(AndroidJUnit4::class)
    class MyTestSuite {
        @Test fun testEvent() {
            val scenario = launchActivity<MyActivity>()
            scenario.onActivity { activity ->
              startActivity(Intent(activity, MyOtherActivity::class.java))
            }

            val originalActivityState = scenario.state
        }
    }
    

활동 다시 생성

기기의 리소스가 부족하면 시스템이 활동을 제거할 수 있습니다. 따라서 사용자가 앱으로 돌아올 때 앱이 활동을 다시 생성해야 할 수 있습니다. 이러한 상황을 시뮬레이션하려면 다음과 같이 recreate()를 호출합니다.

    @RunWith(AndroidJUnit4::class)
    class MyTestSuite {
        @Test fun testEvent() {
            val scenario = launchActivity<MyActivity>()
            scenario.recreate()
        }
    }
    

ActivityScenario 클래스는 @NonConfigurationInstance를 사용하여 주석이 지정된 객체 및 활동의 저장된 인스턴스 상태를 유지합니다. 이러한 객체는 테스트 중인 활동의 새 인스턴스에 로드됩니다.

활동 결과 검색

완료된 활동과 연결된 결과 코드 또는 데이터를 얻으려면 다음 코드 스니펫에서와 같이 ActivityScenario 객체 내의 result 필드 값을 가져와야 합니다.

    @RunWith(AndroidJUnit4::class)
    class MyTestSuite {
        @Test fun testResult() {
            val scenario = launchActivity<MyActivity>()
            onView(withId(R.id.finish_button)).perform(click())

            // Activity under test is now finished.

            val resultCode = scenario.result.resultCode
            val resultData = scenario.result.resultData
        }
    }
    

활동에서 작업 트리거

ActivityScenario 내의 모든 메서드는 차단 호출이므로 API를 사용하려면 계측 스레드에서 메서드를 실행해야 합니다.

테스트 중인 활동에서 작업을 트리거하려면 다음과 같이 Espresso 뷰 매처를 사용하여 뷰의 요소와 상호작용하세요.

    @RunWith(AndroidJUnit4::class)
    class MyTestSuite {
        @Test fun testEvent() {
            val scenario = launchActivity<MyActivity>()
            onView(withId(R.id.refresh)).perform(click())
        }
    }
    

그러나 활동 자체에서 메서드를 호출해야 한다면 다음과 같이 ActivityAction을 구현하여 안전하게 실행할 수 있습니다.

    @RunWith(AndroidJUnit4::class)
    class MyTestSuite {
        @Test fun testEvent() {
            val scenario = launchActivity<MyActivity>()
            scenario.onActivity { activity ->
              activity.handleSwipeToRefresh()
            }
        }
    }
    

Android 테스트의 스레딩 작동 방식에 관해 자세히 알아보려면 테스트의 스레드 이해를 참조하세요.