본문 바로가기
기타/세미나

if kakao 2021 - UI 테스트 경험기

by 헤콩 2021. 11. 18.
반응형

if kakao 2020을 봤던게 얼마 안된 것 같은데 벌써 1년이 지나버렸어요!

그래서 오늘은 며칠 전 열렸던 if kakao 2021UI 테스트 경험기 영상에 대한 정리를 하려고 합니다. 아직까지 테스트 코드에 대해 잘 알지는 못해서 스스로에게 도움이 될 것 같아 영상을 보며 정리했습니다. UI 테스트 경험기 에서는 카카오톡에 UI 테스트를 도입해보며 겪었던 경험을 풀어주셨습니다.

 

 


다음 화면을 보면, UI Test에서 어플리케이션을 실행하고 버튼을 눌러 다음화면으로 이동하는 코드가 아주 간결하다는 것을 알 수 있습니다.

이렇게 처음 만난 UI Test는 간단하고 접근하기도 쉬워 보였습니다.

 

 

 

UI Test

UI Test의 API 동작은 크게 3가지로 묶어볼 수 있습니다.

  1. 조회 : 화면의 요소 조회
  2. 상태 : 조회한 요소의 상태 체크
  3. 동작 : 가져온 요소의 터치 등의 사용자 이벤트 전달

그럼 예시를 통해 위에서 소개한 3가지 동작을 살펴볼까요?

 

 

먼저 첫 번째 예시로,

아래 그림에서 보이는 World 라는 체크박스를 체크하도록 하는 UI Test 과정을 살펴보겠습니다.

 

(1) 조회

        i ) StaticText 요소에 대한 XCUIElementQuery를 생성 - 요소에는 여러 타입이 있기 때문에, 'World' 라는 체크박스를 구성하는 요소 중에서 문자열을 나타내는 화면요소를 뜻하는 StaticText 요소를 먼저 조회합니다.

        ii ) 'World' 문자열 요소를 조회 - StaticText 중에서도 'World' 라는 문자열을 가진 요소를 조회합니다.

        iii ) XCUIElement 를 습득 - 해당 화면 요소의 동작을 전달하거나 상태를 알려주는 XCUIElement 객체를 가져옵니다.

        iV ) 조회한 요소에 사용자 터치 이벤트를 전달

 

(2) 상태

조회한 요소의 상태를 체크합니다. 이 때 자주 쓰이는 메서드는 아래와 같습니다.

  • exists : 검색한 요소가 실제로 존재하는지 체크합니다.
  • waitForExistence(timeout: TimeInterval) : 화면에 해당 요소가 나타날 때까지 일정한 간격으로 계속 조회합니다.

(3) Element Type

  • UI 버튼 등의 접근성 타입에 대응하는 타입
  • Enum으로 구성

(4) Identifier

UI Test에서 Identifier란 하나의 값이 아닌 접근성의 여러 문자열 요소들을 동시에 가리키고 있습니다. 아래의 코드는 모두 동일한 내용인데, 첫 번째 코드와 두 번째 코드를 까보면 모두 마지막 코드를 실행시키고 있는 것을 볼 수 있습니다.

 

 

그렇다면 위와 같은 화면에서 World가 아닌 마지막에 있는 긴 문자열 체크박스를 체크하려면 어떻게 할 수 있을까요?

전체 문자열을 Identifier로 사용할 수도 있지만, 위의 Identifier 부분에서 설명한 코드의 첫 번째 / 두 번째 코드처럼 subscription을 사용한 조회나 identifier를 파라미터로 받는 방법으로 조회할 경우 글자수 제한과 관련한 예외가 발생할 수 있습니다. 이 경우에는, 마지막 코드처럼 NSPredicate를 사용하여 다양한 조건으로 조회를 하면 됩니다.

 

 

 

그럼 두 번째 예시를 보겠습니다.

이번 화면에서는 전화번호를 입력하고 버튼을 클릭해 다음화면으로 넘어갑니다. 그리고 다음 화면은 SMS를 통해 인증번호를 입력하는 화면이 나옵니다. 여기서 UITest의 어려운 벽을 마주쳤습니다.

 

첫 번째 벽: 시스템 UI

시스템 UI 는 위 화면에서 볼 수 있는 것 처럼 System Alert, System Push Banner 등을 말합니다. 여기서 우리는 시스템 UI 의 데이터를 어떻게 가져올 수 있을까요? 예시에 빗대어 말하자면, 우리는 어떻게 인증번호 문자의 내용을 가져올 수 있을까요?

 

[1] 시스템 UI 핸들링하기

addUIInterruptionMonitor( ) 메서드를 통해 테스트와 비동기로 동작하는 핸들러를 추가할 수 있습니다. 이렇게 하면 시스템 UI 이벤트를 가로채서 처리할 수 있게 되죠.

  • 시스템의 XCUIElement를 전달
  • 반환값을 통해 다음 인터럽션으로 이벤트를 넘길지 선택 가능
  • element의 디버깅을 통해 호출하는 상위 어플리케이션의 identifier를 알아낼 수 있음
  • 다만, 테스트의 흐름과 상호작용하는 경우 의도대로 동작하지 않는 경우가 있음

[2] 스프링보드에 접근하기

위에서 설명한 [1] 방법은 UI테스트와 비동기로 동작하기 때문에, 가로채진 UI Event와 테스트 중인 화면과의 상호작용이 필요할 경우 어려움이 많습니다. 이 [2] 방법을 사용하면 상호작용하는 테스트를 아주 쉽게 작성할 수 있습니다.

  • 스프링보드의 XCUIApplication을 생성
  • 스프링보드의 모든 접근성 피처에 접근이 가능
    • 앱 아이콘, 상태 바, Alert, Push Banner 등

 

메시지에서 인증번호를 얻어오는 방법은 2 가지가 있습니다.

첫 번째로, 배너 XCUIElement의 라벨은 메시지의 String을 반환하는데 여기서 직접 추출하는 방법이 있습니다.

두 번째로, 아이폰의 SMS 암호 자동 채우기는 보이스 오버 접근성을 지원하는데, 이것을 이용하는 방법입니다.

 

 

두 번째 벽: 두 개의 Textfield

Textfield에 키보드의 포커스를 이동하기 위해서는 사용자의 터치 이벤트를 전달하면 되고, 단순히 각 Textfield에 포커스를 이동해서 암호를 입력하면 되는 간단한 테스트 코드 입니다.

 

하지만 특정 조건에서 두 개 이상의 Textfield가 있을 때 포커스의 이동과 관련한 이슈가 있습니다.

  • 모든 뷰에서 키보드 포커스를 찾지 못했다는 에러와 함께 테스트 종료
  • 하드웨어 키보드가 연결되어 있을 때 발생
  • 커서는 이동하지만 키 이벤트 발생이 불가능하여 에러 발생

 

해당 문제를 해결하는 방법은 2가지가 있는데, 이를 실행하는 방법은 3가지가 있습니다.

1. 시뮬레이터의 plist 수정

먼저 시뮬레이터는 어플리케이션이기 때문에 자신의 설정값이 존재합니다. 시뮬레이터가 처음 만들어지면 키보드의 기본 연결설정이 하드웨어인데, 이를 설정에서 직접 소프트웨어로 바꿔주는 방법으로 해결할 수 있습니다.

  • ~/Library/preferences/com.apple.iphonesimulator.plist
  • ConnectHardwareKeyboard 항목의 값을 false로 수정

2. 소프트웨어 키보드 사용

시뮬레이터에서 소프트웨어 키보드로 변경하거나 앱을 실행할 때 아이폰의 키보드 설정과 관련한 UITextInputModeprivate method를 사용하여 직접 소프트웨어 키보드를 변경하는 방법이 있습니다. 하지만 이 방법은 모두 테스트환경이 아닌 곳에서 작업해야하고, 하드웨어 키보드가 필요한 경우 다시 변경해야한다거나 앱의 코드를 직접 수정하는 방법을 사용해야하는 등 불편함을 유발하며 우리가 언젠가 자동화 테스트를 실행하고 싶을 때 방해가 될 가능성이 큽니다.

 

3. 홈 다녀오기

간단하게 다른 Textfield로 포커스를 이동하기 전에 잠시 홈 화면을 다녀오는 방법으로도 해결할 수 있습니다. 테스트코드만으로 하드웨어 키보드와 Textfield의 이슈를 해결할 수 있습니다.

 

 

 

반응형

댓글