×
Copy
Open
Link
Embed
Share
Beginning
This slide
Copy link URL
Copy link URL
Copy iframe embed code
Copy iframe embed code
Copy javascript embed code
Copy javascript embed code
Share
Tweet
Share
Tweet
Slide 1
Slide 1 text
Unit Test부터 UI Test까지 부현식
Slide 2
Slide 2 text
Who am I?
Slide 3
Slide 3 text
부현식 컴퓨터 공학 전공 삼성전자 무선사업부 (2년차 개발자) Bixby2.0 Client 개발 안드로이드, TDD, 자동화, 블록체인 Github : boohyunsik Blog : boohyunsik.github.io
Slide 4
Slide 4 text
Contents 1. Unit test 와의 첫 만남? 2. Unit test 의 진가 3. UI Testing 까지!
Slide 5
Slide 5 text
Unit test 에 대한 편견?
Slide 6
Slide 6 text
귀찮다. 그거 짤 시간이 어디있냐. 빌드할 때 자꾸 남의 TC가 죽어서 싫다. TC 짜는 법 배우기 귀찮다.
Slide 7
Slide 7 text
대학생때의 나 객체 지향 프로그래밍..? 그거 먹는건가요.. 프로그램은 돌아가기만 하면 되지~ 어차피 과제내면 안 볼 코드들이야~ 대기업 가려면 알고리즘 문제 푸는게 우선이야!
Slide 8
Slide 8 text
Unit testing과의 첫 만남? 소프트웨어 공학 시간…
Slide 9
Slide 9 text
Example
Slide 10
Slide 10 text
Example
Slide 11
Slide 11 text
이걸 굳이 왜…?
Slide 12
Slide 12 text
Unit testing의 진가 공모전
Slide 13
Slide 13 text
Retrofit 따릉이정보를 보여주는 Android app 제작 식당 정보를 받아오기 위해 Retrofit을 이용
Slide 14
Slide 14 text
But… Retrofit을 처음 써보는 상황 Rest API? 뭐지 그게…
Slide 15
Slide 15 text
But… Unit test는 머릿속에 존재도 하지 않음… 안드로이드 개발도 해본 경험이 별로..
Slide 16
Slide 16 text
How to test? Retrofit을 이용해서 축제 정보 받아오는 로직 구현 로그로 받아온 정보를 다 찍고
Slide 17
Slide 17 text
How to test? APK를 설치해서 데이터를 실제로 받아오는 곳까지 직접 들어가서 로그를 확인!
Slide 18
Slide 18 text
How to test? 또한 Rest API는 Postman을 이용하거나 Retrofit은 새로운 Java 프로젝트를 만들어서 테스트!
Slide 19
Slide 19 text
매우 매우 귀찮고 비효율적인 것 같다…
Slide 20
Slide 20 text
Unit test를 활용해보자!
Slide 21
Slide 21 text
간단한 배경지식… Mocking : 테스트용 가짜 객체를 만드는 것 Assert : 조건에 부합하지 않으면 프로그램을 종료함
Slide 22
Slide 22 text
Unit test를 활용해보자! Retrofit을 이용하여 따릉이 정보를 가져오는 메소드
Slide 23
Slide 23 text
결과! 간단하게 유닛 테스트 작성
Slide 24
Slide 24 text
메소드 단위로 실행 즉석에서 메소드 단위로 실행 가능!
Slide 25
Slide 25 text
뭐가 좋은가? 굳이 App을 실행하여 테스트 할 필요가 없음 메소드 단위로 실행하여 따릉이 api를 잘 쓰고 있는지 간단하게 테스트 가능!
Slide 26
Slide 26 text
이거 좀 쓸만한데…? (감이 오기 시작…)
Slide 27
Slide 27 text
다른 부분에도 Unit test를 적용해보자!
Slide 28
Slide 28 text
그러나 이미 프로젝트는 산으로…
Slide 29
Slide 29 text
Refactoring for Test Code !
Slide 30
Slide 30 text
테스트를 방해하는 요소들 1. 복잡한 의존과 강한 결합 2. 덩치가 큰 메소드
Slide 31
Slide 31 text
복잡한 의존과 강한 결합 객체끼리 직접 결합하고 있는 경우!
Slide 32
Slide 32 text
복잡한 의존과 강한 결합 ToggleButton이 하나 있는 액티비티
Slide 33
Slide 33 text
Activity에 있는 ToggleButton이 눌려있는지 반환하는 기능을 제공하는 Example 클래스
Slide 34
Slide 34 text
간단하게 만들어본 테스트 코드
Slide 35
Slide 35 text
@Before annotation이 붙은 함수는 각 테스트 함수 실행 전에 실행됩니다.
Slide 36
Slide 36 text
이 테스트 함수는 isToggleSelectedInActivity가 반환하는 값을 출력합니다.
Slide 37
Slide 37 text
테스트 실패입니다 ㅠ.ㅠ
Slide 38
Slide 38 text
왜 실패할까…?
Slide 39
Slide 39 text
강하게 결합하는 구조는 테스트하기 어렵다!
Slide 40
Slide 40 text
이유는 많더라.. 1. 안드로이드 디바이스에 엮인 객체라던가 2. 의존하는 클래스가 또 다른 컴포넌트에 의존 한다던가 3. 서버 통신이나 인증 과정이 필요한 경우나…
Slide 41
Slide 41 text
Android Device Activity JVM Activity? 액티비티는 안드로이드 OS가 만들어줘야 의미를 갖지, 내 컴퓨터의 JVM 위에서는 의미가 없다!
Slide 42
Slide 42 text
그리고 어찌어찌 안드로이드 의존을 잘 해결했더라도 이 함수는 정해진 값 만을 return하게 됨
Slide 43
Slide 43 text
결합을 약하게!
Slide 44
Slide 44 text
테스트 코드 상에서 실행하기 힘들었던 MainActivity를, 테스트용 View로 바꿀수 있다
Slide 45
Slide 45 text
인터페이스로 구현
Slide 46
Slide 46 text
Example이 MainActivity를 MainView 인터페이스를 통해 의존하도록 변경!
Slide 47
Slide 47 text
상황에 맞는 객체를 내 마음대로 주입할 수 있다. isToggleSelectedActivity가 true인 경우 isToggleSelectedActivity가 false인 경우
Slide 48
Slide 48 text
interface MainView 테스트 코드 상에서 실행하기 힘들었던 MainActivity를, 테스트용 View로 바꿀수 있다 True를 반환하는 Activity Example False를 반환하는 Activity Constructor
Slide 49
Slide 49 text
이렇게 가짜 객체를 만드는 걸 Mocking 이라고 이해하면 될 것 같다!
Slide 50
Slide 50 text
이런 경우… 메소드 안에서 Intent 객체를 새로 생성하는 상황
Slide 51
Slide 51 text
마찬가지로 에러를 맛보게 됩니다…
Slide 52
Slide 52 text
Context, Intent, Bundle 처럼 안드로이드에 의존하는 객체들은 Mocking을 해주던지, build option을 바꿔줘야 함
Slide 53
Slide 53 text
빌드 옵션을 바꾸어도 내가 원하는 대로 동작하지 않음!
Slide 54
Slide 54 text
Mockito등을 이용해 Mocking을 하더라도 활용할 수가 없다. (객체가 메소드 안에서 만들어지기 때문)
Slide 55
Slide 55 text
어떻게 해결할까?
Slide 56
Slide 56 text
의존성 주입(DI)를 적극적으로 활용하거나 Factory pattern 비스무리한 모양을 이용해보자!
Slide 57
Slide 57 text
함수 Parameter로 주입 받는 경우
Slide 58
Slide 58 text
Factory 패턴을 흉내내서 만든 Injector (PowerMock을 이용하여 static class mocking 가능)
Slide 59
Slide 59 text
그 외 Dagger나 Koin같은 DI library 사용도 고려할 수 있습니다.
Slide 60
Slide 60 text
내가 만든 mock 객체를 주입해서 테스트 할 수 있다.
Slide 61
Slide 61 text
1. 인터페이스와 추상이 어떤 효과를 갖는지 알겠다! 2. 다형성에서 말하는 갈아 끼운다가 어떤 뜻인지 알겠다! 3. 의존성 주입이 테스트에 어떤 영향을 미치는지 알겠다!
Slide 62
Slide 62 text
덩치가 큰 메소드
Slide 63
Slide 63 text
…
Slide 64
Slide 64 text
뭘 테스트 해야 하지…?
Slide 65
Slide 65 text
쓰레드 시작하면서 토큰 정의
Slide 66
Slide 66 text
Connection 정의하면서 파라미터 추가 버퍼 생성
Slide 67
Slide 67 text
받아온 데이터 Json 파싱
Slide 68
Slide 68 text
액티비티 전환
Slide 69
Slide 69 text
Firebase 데이터 전송 및 Toast 띄우기
Slide 70
Slide 70 text
이 메소드가 하는 일이 너무 많아서 테스트 해야 할 게 너무 많다!!
Slide 71
Slide 71 text
메소드 크기를 작게 유지해야 테스트 하기 편하겠다!
Slide 72
Slide 72 text
Connection 생성해서 데이터 받아오는 메소드 -> 제대로 받아오는지 테스트
Slide 73
Slide 73 text
받아온 Json 데이터를 파싱하는 메소드 -> 예제 데이터를 넣고 제대로 파싱하는지 테스트
Slide 74
Slide 74 text
액티비티 전환 및 Toast 실행 메소드 -> 내가 의도한 인터페이스가 실행되는지 테스트
Slide 75
Slide 75 text
앞서 설명한 것들을 전부 묶어서 Integration Test!
Slide 76
Slide 76 text
Unit test의 효과
Slide 77
Slide 77 text
애매했던 객체 지향 프로그래밍의 개념들에 대한 이해 인터페이스와 다형성, DI에 대해!
Slide 78
Slide 78 text
테스트 하기 좋은 코드에 대해 고민하기 시작
Slide 79
Slide 79 text
TDD, 개발 방법론, 소프트웨어 아키텍처
Slide 80
Slide 80 text
CI에서의 Test case 빌드 시 테스트 케이스를 모두 실행 내 수정사항으로 인해 다른 테스트 케이스가 실패한다면? 프로그램에 버그가 발생할 가능성이 있다는 것!
Slide 81
Slide 81 text
Open Source 에서의 Test case 코드를 보는 것 vs 테스트 코드를 보는 것
Slide 82
Slide 82 text
유닛 테스트를 작성함으로써 코드의 품질을 높일 수 있다! (시작이 반이라고..)
Slide 83
Slide 83 text
UI Test 까지!
Slide 84
Slide 84 text
Bixby UI Test 많은 종류의 사용자 명령 … 어떻게 테스트 하지?
Slide 85
Slide 85 text
UI Automator2 외부에서 앱을 조작해주는 테스트 라이브러리 (Android Accessibility 이용)
Slide 86
Slide 86 text
이렇게 컴포넌트를 쉽게 찾고
Slide 87
Slide 87 text
이벤트도 쉽게 발생시킬 수 있다!
Slide 88
Slide 88 text
또한 하드웨어 버튼 이벤트도 발생시킬 수 있다!
Slide 89
Slide 89 text
Device 객체를 만들고
Slide 90
Slide 90 text
Home 버튼을 누르고
Slide 91
Slide 91 text
Package 이름을 통해 앱을 찾는다.
Slide 92
Slide 92 text
또한 패키지 이름을 통해 앱을 실행시킨다.
Slide 93
Slide 93 text
앱이 실행될 때 까지 기다린다.
Slide 94
Slide 94 text
Resource ID를 기준으로 View를 찾고, 텍스트를 넣어준다.
Slide 95
Slide 95 text
Resource ID 기준으로 View를 찾고 클릭한다.
Slide 96
Slide 96 text
Resource ID가 “testToBeChanged” 인 View가 나타날 때 까지 기다린다.
Slide 97
Slide 97 text
View에 text가 의도한 결과와 같은지 비교한다.
Slide 98
Slide 98 text
기계적으로 반복해야 하는 검증을 자동화 할 수 있다.
Slide 99
Slide 99 text
날씨 알려줘, 맛집 알려줘, 알람 맞춰줘, …
Slide 100
Slide 100 text
하드웨어 이벤트, 다양한 기준으로 View를 찾고 이벤트를 발생시킬 수 있는 강력한 라이브러리!
Slide 101
Slide 101 text
꼭 한번 사용해보세요 :)
Slide 102
Slide 102 text
감사합니다.