안드로이드 테스트(android test)
장점
1. 개발단계에서 초기오류를 감지할수있다
2. 코드리팩토링을 할수있다
3. 안정적인 개발속도
테스트를 위해선 무엇이 준비되어야 할까요?
-> 특정패턴의 아키텍쳐를 따라야 한다. ex) 예를 들면 View를 위해 MVP,MVVM 패턴을 네트워킹과 데이터 접근을 위해 Repository 패턴을 구현해 테스트
할수있는 구조를 갖춘다.
테스트는 단위 테스트와 UI테스트로 나뉘는데 단위테스트는 로컬단위 테스트, 계측단위 테스트로 나뉜다. UI테스트는 일반적으로 계측기반의 테스트이다.
소규모 테스트는 프로덕션 시스템과 별도로 실행할수있는 단위테스트로 일반적으로 모든 구성요소를 모의 테스트하며 빠르게 실행해야 한다.
중간규모 테스트는 작은 테스트와 큰 테스트 사이에 있는 통합 테스트입니다. 여러 구성요소를 통합하여 에뮬, 실제장치에서 실행된다.
대규모 테스트는 UI 워크 플로를 완료하여 실행되는 통합 및 UI테스트 에뮬이나 실제장치에서 예상대로 작동하는지 확인한다.
1. 단위(unit) 테스트
- 앱의 기능을 추가하고 변경하면 해당 기능에 대한 단위 테스트를 만들고 의도한대로 동작하는지에 대해 확인한다. 유닛을 테스트하고 필요에 따라 stubbed or mocked method를 추가하여 안드로이드 시스템과 상호작용할수있다
(1) roboletric - android sdk가 제공하는 클래스에 가짜동작을 심어서 jvm에서 android 코드를 실행하는 단위 테스트 프레임워크
1) 왜 유용하냐?
1. jvm에서 테스트하기 어려운코드가 존재한다. (Log나 View등)
2. View객체를 별도의 mock없이도 그대로 사용가능(mock을 쓰기 어려운 구조 getviewbyid, getsystemservice도 가능하다)
3. Log.i같은 static메서드도 바로 기본동작을 수행가능하다
4. Build.VERSION 클래스 정보를 마음대로 설정가능하다.
HTTP API 파싱 테스트 -> 예상되는 호출결과를 고정해서 테스트하기
-> 예외테스트에 특히 유용하다 (비정상적인 응답(서버점검중...), 변화가 예상되는 응답)
(2) Mockito - 자바에서 단위테스트를 하기 위해 MOCK을 만들어주는 프레임워크
구현기능에 대한 동작여부나 예외에 대한 검증이 가능하다.
@Mock, @Spy, @Captor, @InjectMock과 같은 Annotation을 통해 쉽게 Mocking, Stubbing 가능하다.
Mock - Mock Object 생성,
Verify - 원하는 메소드가 특정조건으로 실행되었는지 검증
Stub - 메소드행동을 원하는대로 미리 정해주는것을 말한다. when, thenReturn, thenThrow등을 사용해 MOCK의 메소드 리턴값 or 예외발생을 정할수있다.
Spy - 진짜 인스턴스를 mock하는것
anyInt, anyFloat, anyString, eq로 넘기는 갓ㅄ에 대한 특정조건을 지정
Argument matcher - anyInt, anyString의 커스터 마이즈 버전
Argument Captor - 위와 비슷하나 따로 클래스를 만들 필요 없다.
verification에서만 사용가능하다.
verfication with timeout -> verify(mock.timeout(200)).size()
체이닝을 사용해 mock생성과 stub을 한줄에 생성
when(mocklist.class).get(0).thenReturn(1).thenReturn(3).thenthrow~~
(3) PowerMock - 코드 구조가 복잡하거나 테스트하기 힘든 부분들을 피해 유닛테스트를 할 수 있게 해준다.
1. 캡슐화 우회 - private 변수, 메서드 접근 가능
2. 부모클래스의 private 변수, 메서드 접근 가능
3. private 생성과 접근 가능
4. final 클래스, 메소드 접근 가능
(4) JUnit4 - 자바에서 널리 사용되고 있는 단위 테스트 프레임워크
(5) Android junit Runner 클래스는 android에서 junit3 or junit4 스타일 테스트 클래스로 실행할수 있게 해주는 계측기반 junit 테스트 러너이다.
(6) Android Test orchestrator - 기기에서 완전히 테스트 분리를 실현할 수 있게 해준다. 테스트간의 공유상태를 줄이고 테스트가 다운되면 나머지
테스트도 할수 없게 되는 문제를 방지한다.
2. UI 테스트
(1) Espresso Test recorder - 테스트 코드를 전혀 작성하지 않고도 앱의 UI테스트를 생성한다.
UI 상호작용 및 View요소의 assertion으로 구성된다.
1) UI 상호작용을 기록한다.
2) UI 요소 확인을 위해 assertion 추가
3) 기기에서 테스트 진행
4) Firebase Test Lab에서 진행
(2) Espresso - 단일 앱 UI테스트 프레임워크로 계측기반의 API이고 AndroidJunitRunner와 함께 작동한다.
1) onView or onData를 호출하여 UI구성요소를 찾는다.
2) viewInteraction.perform or dataInteraction.perform 메소드를 호출하고 사용자 액션을 전달하여 특정 UI 상호작용을 테스트할수있다.
3) 위의 단계를 반복하여 사용자 흐름을 시뮬레이션한다.
4) ViewAssertion 메서드를 사용하여 UI가 예상된 상태 or 동작을 반영하는지 확인한다.
@Before -> 테스트 시작전 실행 @After -> 테스트 후 실행
5) View Matchers 클래스 메소드 지원
onView(withText("sign-in")) - 해당 글자뷰 찾기
onView(withId(R.id.button_sign)) - 해당 리소스 id뷰 찾기
6) Hamcrest Matchers 클래스 사용
onView(allof(withid(R.id.button_sign, withText("sign-in"))
1. allof - 모든 조건이 일치하는지 체크
2. anyof - 하나의 조건이라도 일치하는지 체크
3. not - 조건과 일치하지 않는지 체크
7) AdapterView - ListView, RecyclerView, GridView, Spinner
onView 대신에 onData사용하고 DataInteraction사용한다.
perform - 사용자액션을 시뮬레이션, 하나이상의 ViewAction객체를 인수로 전달한다.
8) ViewActions.click() - 클릭
.typetext - 뷰를 클릭하고 지정된 문자열 입력
.scrollto - 스크롤하기
.presskey - 지정된 키보드로 키 실행
.clearText - 문자열 지운다.
9) Espresso Intent - 앱에서 전송한 인텐트의 유효성 검사 및 결과를 stub후 테스트 중인 구성요소로 다시 보내서 테스트
10) Espresso webview - webview구성요소를 테스트할 수 있다. javascript활성화
11) Espresso core - 핵심 및 기본 viewmatcher, 액션 및 어설션 포함
(3) UI Automator - 멀티 앱의 UI 테스트 프레임워크로 계측기반의 api, AndroidJunitRunner와 함께 사용한다.
- 구성요소에 텍스트 레이블, contentdescription 값들이 다 있는지 확인한다. (접근성기능을 구현한 앱)
UIAutomatorViewer도구로 ui 레이아웃계층구조 검사, 속성을 볼 수 있다.
1) UIDevice Object 생성 - getInstance 호출
2) findObject 호출 - 장치에 표시된 ui구성요소에 액세스, UIObject객체 리턴
3) UIObject 객체 메서드를 호출하여 특정 사용자 상호작용을 수행한다. ex)setText : 텍스트편집
4) 2,3 단계를 반복, 사용자 상호작용 테스트
5) 예상된 상태, or 동작을 반영하는지 확인한다.
6) UIDevice 객체는 다양한 디바이스속성을 알수 있다. 장치를 특정 회전으로 강제실행하고 d패드 하드웨어버튼을 누르는 등 장치수준의 작업을 수행할수 있다.
7) UISelector 클래스 : 특정ui구성요소 액세스하려면 사용하는데 현재 표시된 ui의 특정요소에 대한 쿼리를 나타낸다.
일치하는 구성요소가 두개이상 발견되면 UIObject를 리턴한다.
childSelector메서드 - 여러 uiselector인스턴스를 중첩할수있다.
uiObject.click - 클릭
uiObject.dragto - 드래그
uiObject.setText - 텍스트편집
" swipeUp(), swipeLeft(), swipeDown(), swipeRight() - swipe
getContext를 가져와 인텐트를 보내거나 액티비티를 시작할수 있다.
8) UICollection 클래스 - 컬렉션에 대한 작업을 수행, ui컨테이너 or 다른 자식ui요소의 래퍼를 검색하는 uiselector를 지정한다.
9) UIScrollable 클래스 - 스크롤 시뮬레이션
결과 확인 - 표준 junitAssert 메서드를 사용하여 예상결과를 반환하는지 테스트
3. 앱 구성요소 통합 테스트
- 서비스, 콘텐츠 제공자가 앱과 상호작용이 잘되는지 테스트한다.
브로드캐스트리시버는 별도의 테스트케이스클래스가 없다. ->인텐트를 보내서 테스트한다.
1. 서비스 테스트 - ServiceTestRule 클래스는 단위테스트 메소드가 실행되기 전에 서비스를 시작하고 테스트가 완료되면 종료하는 junit4테스트
IntentService는 지원하지 않음
2. 콘텐츠 제공자 테스트 - ProviderTestcast2 클래스를 사용해 실제 데이터에 영향을 주지 않고 독립적으로 테스트한다.
isolatedcontext, mockcontentResolver 와 같은 안드로이드 mock객체클래스를 사용하여 액세스한다. 격리된 테스트환경에서
작업하는것으로 제한된다. query, insert, delete, update ~~
4. UI 성능 테스트
(1) 프레임 체크 (초당 60프레임)-> jank체크
-> adb shell dumpsys gfxinfo - 프레임 성능 정보 출력
adb shell dumpsys gfxinfo <package-name> framestats - 마지막 20프레임정보 출력
framestats 데이타형식 - 데이터블록은 csv형식으로 출력
android 6.0부터 jank양과 심각도 체크하는 새로운 로그기능이 있다.