1page.title=표시 성능 테스트 2page.image=images/cards/card-test-performance_2x.png 3page.keywords=성능, FPS, 도구 4 5@jd:body 6 7 8<div id="qv-wrapper"> 9 <div id="qv"> 10 <h2>이 문서의 내용</h2> 11 <ol> 12 <li><a href="#measure">UI 성능 측정</a> 13 <ul> 14 <li><a href="#aggregate">프레임 상태 집계</a></li> 15 <li><a href="#timing-info">정확한 프레임 타이밍 정보</a></li> 16 <li><a href="#timing-dump">단순한 프레임 타이밍 덤프</a></li> 17 <li><a href="#collection-window">상태 수집 창 제어</a></li> 18 <li><a href="#diagnose">성능 저하 진단</a></li> 19 <li><a href="#resources">추가 리소스</a></li> 20 </ul> 21 </li> 22 <li><a href="#automate">UI 성능 테스트 자동화</a> 23 <ul> 24 <li><a href="#ui-tests">UI 테스트 설정</a></li> 25 <li><a href="#automated-tests">자동화된 UI 테스트 설정</a></li> 26 <li><a href="#triage">관측된 문제 심사 및 수정</a></li> 27 </ul> 28 </li> 29 </ol> 30 </div> 31</div> 32 33 34<p> 35 사용자 인터페이스(UI) 성능 테스트를 수행하면 앱이 기능적인 요건에 부합할 뿐만 아니라 사용자가 앱과 부드럽고 매끈하게 상호작용하며 초당 60 프레임의 일관된 속도로(<a href="https://www.youtube.com/watch?v=CaMTIgxCSqU&index=25&list=PLWz5rJ2EKKc9CBxr3BVjPTPoDPLdPIFCE">왜 60fps일까요?</a>) 생략되거나 지연된 프레임, 또는 전문 용어로 <em>jank</em>(프레임이 넘어가는 현상)가 없이 실행되게 보장할 수 있습니다. 36 37 38 이 문서에서는 UI 성능을 측정하는 데 사용할 수 있는 몇 가지 도구를 설명하고, 테스트 방법에 UI 성능 측정법을 통합하는 데 쓰이는 접근법을 보여드립니다. 39 40 41</p> 42 43 44<h2 id="measure">UI 성능 측정</h2> 45 46<p> 47 성능을 개선하려면 우선 시스템의 성능을 측정할 수 있는 능력부터 갖추고, 그 다음에 파이프라인의 여러 부분에서 나올 수 있는 다양한 문제를 진단하고 식별해야 합니다. 48 49 50</p> 51 52<p> 53 <em><a href="https://source.android.com/devices/tech/debug/dumpsys.html">dumpsys</a></em>는 Android 도구의 일종으로 기기에서 실행되면서 시스템 서비스의 상태에 대한 흥미로운 정보를 덤프하는 역할을 합니다. 54 55 <em>gfxinfo</em> 명령을 dumpsys에 전달하면 기록 단계 중에 발생하는 애니메이션 프레임과 관련된 성능 정보가 담긴 logcat으로 출력을 제공합니다. 56 57 58</p> 59 60<pre> 61> adb shell dumpsys gfxinfo <PACKAGE_NAME> 62</pre> 63 64<p> 65 이 명령은 프레임 타이밍 데이터의 서로 다른 변형을 여러 개 작성할 수 있습니다. 66</p> 67 68<h3 id="aggregate">프레임 상태 집계</h3> 69 70<p> 71 M 미리 보기에서 이 명령은 프레임 데이터의 집계된 분석을 logcat으로 출력합니다. 이는 프로세스의 전 수명을 통틀어 수집한 것입니다. 72 예를 들면 다음과 같습니다. 73</p> 74 75<pre class="noprettyprint"> 76Stats since: 752958278148ns 77Total frames rendered: 82189 78Janky frames: 35335 (42.99%) 7990th percentile: 34ms 8095th percentile: 42ms 8199th percentile: 69ms 82Number Missed Vsync: 4706 83Number High input latency: 142 84Number Slow UI thread: 17270 85Number Slow bitmap uploads: 1542 86Number Slow draw: 23342 87</pre> 88 89<p> 90 이와 같은 높은 레벨의 통계는 레벨이 높을 때 앱의 렌더링 성능을 나타내며, 이외에도 여러 프레임에 걸친 앱의 안정성을 나타내기도 합니다. 91 92</p> 93 94 95<h3 id="timing-info">정확한 프레임 타이밍 정보</h3> 96 97<p> 98 M 미리 보기에서는 gfxinfo에 사용할 수 있는 새 명령어를 도입했습니다. 바로 <em>framestats</em>로, 이는 최근 프레임으로부터 극히 상세한 프레임 타이밍 정보를 제공하여 문제를 더욱 정확하게 추적하고 디버그할 수 있습니다. 99 100 101</p> 102 103<pre> 104>adb shell dumpsys gfxinfo <PACKAGE_NAME> framestats 105</pre> 106 107<p> 108 이 명령은 프레임 타이밍 정보를 나노초 타임스탬프로 출력하며, 그 출처는 앱이 만든 마지막 120개의 프레임입니다. 아래는 adb dumpsys gfxinfo 109 <PACKAGE_NAME> framestats에서 가져온 원시 출력을 예로 나타낸 것입니다. 110 111</p> 112 113<pre class="noprettyprint"> 1140,49762224585003,49762241251670,9223372036854775807,0,49762257627204,49762257646058,49762257969704,49762258002100,49762265541631,49762273951162,49762300914808,49762303675954, 1150,49762445152142,49762445152142,9223372036854775807,0,49762446678818,49762446705589,49762447268818,49762447388037,49762453551527,49762457134131,49762474889027,49762476150120, 1160,49762462118845,49762462118845,9223372036854775807,0,49762462595381,49762462619287,49762462919964,49762462968454,49762476194547,49762476483454,49762480214964,49762480911527, 1170,49762479085548,49762479085548,9223372036854775807,0,49762480066370,49762480099339,49762481013089,49762481085850,49762482232152,49762482478350,49762485657620,49762486116683, 118</pre> 119 120<p> 121 이 출력의 각 줄은 앱이 만든 프레임을 나타냅니다. 각 줄에는 정해진 숫자의 열이 있으며 이 열은 프레임 제작 파이프라인의 각 단계에서 소요한 시간을 나타냅니다. 122 다음 섹션에서는 각 열이 무엇을 나타내는지 등, 이 형식에 대해 좀 더 자세히 다뤄보겠습니다. 123 124</p> 125 126 127<h4 id="fs-data-format">Framestats 데이터 형식</h4> 128 129<p> 130 데이터 블록은 CSV 형식으로 출력되기 때문에 이를 개발자가 선택한 스프레드시트 도구에 붙여넣거나 수집해서 스크립트로 구문 분석하기 등의 작업이 매우 단도직입적입니다. 131 다음 표는 출력 데이터 열의 형식을 설명한 것입니다. 132 타임스탬프는 모두 나노초 단위입니다. 133</p> 134 135<ul> 136 <li>플래그 137 <ul> 138 <li>플래그 열에 '0'이 기재되어 있는 행의 경우, 총 프레임 시간을 계산하려면 FRAME_COMPLETED 열에서 INTENDED_VSYNC 열을 빼면 됩니다. 139 140 </li> 141 142 <li>이것이 0이 아니면 그 행은 무시해야 합니다. 해당 프레임이 정상 성능의 이상값인 것으로 판별되었기 때문이며, 여기에서는 레이아웃과 그리기에 16ms 이상이 걸릴 것으로 예상됩니다. 143 144 다음은 이런 일이 일어나는 몇 가지 이유입니다. 145 <ul> 146 <li>창 레이아웃이 변경되었습니다(애플리케이션의 첫 프레임 또는 한 회 회전 이후). 147 148 </li> 149 150 <li>프레임을 건너뛰었을 가능성도 있습니다. 이 경우 몇몇 값에 가비지 타임스탬프가 있을 것입니다. 151 프레임을 건너뛰는 것은 해당 프레임이 60fps를 초과하는 경우 또는 화상에 나타난 것 중 아무 것도 변한 것이 없을 때 등이며, 이는 반드시 앱에 문제가 있음을 나타내는 징후는 아닙니다. 152 153 154 </li> 155 </ul> 156 </li> 157 </ul> 158 </li> 159 160 <li>INTENDED_VSYNC 161 <ul> 162 <li>프레임에 대한 원래 의도한 시작 지점입니다. 이 값이 VSYNC와 다른 경우, UI 스레드에서 발생한 작업이 있어 이것이 vsync 신호에 적절한 시간 내에 응답하지 못하도록 한 것입니다. 163 164 165 </li> 166 </ul> 167 </li> 168 169 <li>VSYNC 170 <ul> 171 <li>Vsync 수신기 전체와 프레임에 대한 드로잉에서 사용된 시간 값입니다.(Choreographer 프레임 콜백, 애니메이션, View.getDrawingTime() 등) 172 173 </li> 174 175 <li>VSYNC와 이것이 애플리케이션에 미치는 영향에 대해 더 자세히 알아보려면 <a href="https://www.youtube.com/watch?v=1iaHxmfZGGc&list=PLOU2XLYxmsIKEOXh5TwZEv89aofHzNCiu&index=23">VSYNC 이해하기</a> 비디오를 확인하십시오. 176 177 178 </li> 179 </ul> 180 </li> 181 182 <li>OLDEST_INPUT_EVENT 183 <ul> 184 <li>입력 대기열에서 가장 오래된 입력 이벤트의 타임스탬프 또는 프레임에 대한 입력 이벤트가 없는 경우 Long.MAX_VALUE입니다. 185 186 </li> 187 188 <li>이 값은 기본적으로 플랫폼 작업을 위해 의도된 것이며 앱 개발자에게는 한정된 정도로 유용한 값입니다. 189 190 </li> 191 </ul> 192 </li> 193 194 <li>NEWEST_INPUT_EVENT 195 <ul> 196 <li>입력 대기열에서 가장 최근 입력 이벤트의 타임스탬프 또는 프레임에 대한 입력 이벤트가 없는 경우 Long.MAX_VALUE입니다. 197 198 </li> 199 200 <li>이 값은 기본적으로 플랫폼 작업을 위해 의도된 것이며 앱 개발자에게는 한정된 정도로 유용한 값입니다. 201 202 </li> 203 204 <li>다만 앱이 얼마나 긴 대기 시간을 추가하고 있는지를 대략적으로 알아볼 수는 있습니다. (FRAME_COMPLETED - NEWEST_INPUT_EVENT)를 살펴보면 됩니다. 205 206 </li> 207 </ul> 208 </li> 209 210 <li>HANDLE_INPUT_START 211 <ul> 212 <li>입력 이벤트가 애플리케이션에 발송된 시점의 타임스탬프입니다. 213 </li> 214 215 <li>이것과 ANIMATION_START 사이의 시간을 보면 애플리케이션이 입력 이벤트를 처리하느라 보낸 시간을 측정할 수 있습니다. 216 217 </li> 218 219 <li>이 숫자가 크면(2ms 초과) 이는 앱이 입력 이벤트를 처리하느라 보기 드물게 긴 시간을 소요한다는 뜻입니다. 예를 들어 View.onTouchEvent()는 이 작업을 최적화해야 하거나 다른 스레드로 오프로드해야 한다는 뜻일 수 있습니다. 220 221 다른 시나리오도 몇 가지 있을 수 있다는 점을 유의하십시오. 예를 들어 새 액티비티를 시작하는 클릭 이벤트나 그와 비슷한 것의 경우, 이 숫자가 클 것을 예상하고 받아들일 수 있습니다. 222 223 224 </li> 225 </ul> 226 </li> 227 228 <li>ANIMATION_START 229 <ul> 230 <li>Choreographer에 등록된 애니메이션이 실행된 시점의 타임스탬프입니다. 231 </li> 232 233 <li>이것과 PERFORM_TRANVERSALS_START 사이의 시간을 보면 실행 중인 애니메니터 전체((ObjectAnimator, ViewPropertyAnimator 및 Transitions가 보편적인 것들임)를 평가하는 데 시간이 얼마나 걸렸는지 판단할 수 있습니다. 234 235 236 </li> 237 238 <li>이 숫자가 크면(2ms 초과), 앱이 사용자 지정 애니메이터를 작성한 적이 있는지 확인하십시오. 아니면 ObjectAnimators가 애니메이션 효과를 실행하는 필드가 어느 것인지 알아보고 이들이 애니메이션에 대해 적절한지 확인해야 합니다. 239 240 241 </li> 242 243 <li>Choreographer에 대한 자세한 정보는 <a href="https://developers.google.com/events/io/sessions/325418001">버터거나 나쁘거나(For Butter or Worse)</a> 비디오를 참조하십시오. 244 245 </li> 246 </ul> 247 </li> 248 249 <li>PERFORM_TRAVERSALS_START 250 <ul> 251 <li>이 값에서 DRAW_START를 빼면 레이아웃과 측정 단계를 완료하는 데 얼마나 걸렸는지 추출할 수 있습니다(스크롤 또는 애니메이션 중에는 이 값이 0에 가까울 것이라는 예상이 나와야 한다는 점을 유의하십시오). 252 253 254 </li> 255 256 <li>렌더링 파이프라인의 측정 및 레이아웃 단계에 대한 자세한 정보는 <a href="https://www.youtube.com/watch?v=we6poP0kw6E&list=PLOU2XLYxmsIKEOXh5TwZEv89aofHzNCiu&index=27">무효화, 레이아웃 및 성능</a> 비디오를 참조하십시오. 257 258 259 </li> 260 </ul> 261 </li> 262 263 <li>DRAW_START 264 <ul> 265 <li>PerformTraversals의 그리기 단계가 시작된 시점입니다. 이것은 무효화된 모든 보기의 표시 목록을 기록하는 시작 지점입니다. 266 267 </li> 268 269 <li>이것과 SYNC_START 사이의 시간이 트리의 모든 무효화된 보기에서 View.draw()를 호출하는 데 걸린 시간입니다. 270 271 </li> 272 273 <li>드로잉 모델에 대한 자세한 정보는 <a href="{@docRoot}guide/topics/graphics/hardware-accel.html#hardware-model">하드웨어 가속</a> 또는 <a href="https://www.youtube.com/watch?v=we6poP0kw6E&list=PLOU2XLYxmsIKEOXh5TwZEv89aofHzNCiu&index=27">무효화, 레이아웃 및 성능</a> 비디오를 참조하십시오. 274 275 276 </li> 277 </ul> 278 </li> 279 280 <li>SYNC_START 281 <ul> 282 <li>드로잉의 동기화 단계가 시작된 시점입니다. 283 </li> 284 285 <li>이것과 ISSUE_DRAW_COMMANDS_START 사이의 시간이 상당히 큰 값인 경우(0.4ms 초과 또는 그와 유사), 일반적으로 새로운 비트맵이 많이 그려져서 이를 GPU에 업로드해야 한다는 뜻입니다. 286 287 288 </li> 289 290 <li>동기화 단계에 대해 더 자세히 알아보려면 <a href="https://www.youtube.com/watch?v=VzYkVL1n4M8&index=24&list=PLOU2XLYxmsIKEOXh5TwZEv89aofHzNCiu">프로필 GPU 렌더링</a> 비디오를 참조하십시오. 291 292 </li> 293 </ul> 294 </li> 295 296 <li>ISSUE_DRAW_COMMANDS_START 297 <ul> 298 <li>하드웨어 렌더러가 GPU에 드로잉 명령을 발행하기 시작한 시점입니다. 299 </li> 300 301 <li>이것과 FRAME_COMPLETED 사이의 시간을 보면 앱이 얼마나 많은 GPU 작업을 생성하고 있는지 대략적으로 알 수 있습니다. 302 Overdraw가 너무 많거나 렌더링 효과가 비효율적인 것 등의 문제가 여기에 나타납니다. 303 304 </li> 305 </ul> 306 </li> 307 308 <li>SWAP_BUFFERS 309 <ul> 310 <li>EglSwapBuffers가 호출된 시점으로, 플랫폼 작업 외에는 비교적 흥미롭지 않습니다. 311 312 </li> 313 </ul> 314 </li> 315 316 <li>FRAME_COMPLETED 317 <ul> 318 <li>모두 끝났습니다! 이 프레임에 작업하느라 소요된 총 시간을 계산하려면 FRAME_COMPLETED - INTENDED_VSYNC를 수행하면 됩니다. 319 320 </li> 321 </ul> 322 </li> 323 324</ul> 325 326<p> 327 이 데이터는 여러 가지 방법으로 사용할 수 있습니다. 한 가지 단순하면서도 유용한 시각화는 프레임 시간의 분배(FRAME_COMPLETED - INTENDED_VSYNC)를 여러 가지 대기 시간 버킷에서 표시한 히스토그램을 예로 들 수 있습니다. 아래 그림을 참조하십시오. 328 329 이 그래프를 보면 한 눈에 대부분의 프레임이 아주 양호했다는 것을 알아볼 수 있습니다. 대부분 16ms 최종 기한(빨간색으로 표시)보다 한참 아래에 있지만, 최종 기한을 크게 넘어선 프레임도 몇 개 있습니다. 330 331 이 히스토그램에서 시간 경과에 따른 변화를 살펴보면 대규모 이동이나 새 이상값이 생성되는 것을 확인할 수 있습니다. 332 이외에도 데이터 내의 수많은 타임스탬프를 근거로 입력 대기 시간, 레이아웃에서 보낸 시간 또는 여타 비슷한 흥미로운 메트릭도 그래프로 표현할 수 있습니다. 333 334 335</p> 336 337<img src="{@docRoot}preview/images/perf-test-framestats.png"> 338 339 340<h3 id="timing-dump">단순한 프레임 타이밍 덤프</h3> 341 342<p> 343 <strong>프로필 GPU 렌더링</strong>이 개발자 옵션에서 <strong>adb 셸의 dumpsys gfxinfo</strong>로 설정된 경우, <code>adb shell dumpsys gfxinfo</code> 명령이 가장 최근의 120개 프레임에 대한 타이밍 정보를 출력하되, 몇 개의 서로 다른 카테고리로 나누어 탭으로 구분된 값을 담아 표현합니다. 344 345 346 이 데이터를 사용하면 드로잉 파이프라인의 어떤 부분이 레벨이 높을 때 느려지는지 나타내는 데 유용합니다. 347 348</p> 349 350<p> 351 위의 <a href="#fs-data-format">framestats</a>와 마찬가지로, 이것을 개발자가 선택한 스프레드시트 도구에 붙여넣거나 수집해서 스크립트로 구문 분석하는 작업은 매우 단도직입적입니다. 352 353 다음 그래프는 앱이 생성한 수많은 프레임이 어디에서 시간을 보내는지 분석한 내용을 표시한 것입니다. 354 355</p> 356 357<img src="{@docRoot}preview/images/perf-test-frame-latency.png"> 358 359<p> 360 Gfxinfo를 실행한 결과, 그 출력을 복사하여 이를 스프레드시트 애플리케이션에 붙여넣은 다음 데이터를 누적 가로 막대형 그래프로 나타내는 것입니다. 361 362</p> 363 364<p> 365 각 세로 막대는 애니메이션 한 프레임을 나타냅니다. 그 막대의 높이가 해당 애니메이션 프레임을 계산하는 데 걸린 밀리초 수를 나타냅니다. 366 막대에서 색이 지정된 각 세그먼트는 렌더링 파이프라인의 각기 다른 단계를 나타내므로, 개발자는 이것을 보고 애플리케이션의 어떤 부분이 병목 현상을 유발하고 있는지 확인할 수 있습니다. 367 368 렌더링 파이프라인을 잘 이해하고 이에 맞게 최적화하는 법에 대한 자세한 내용은 <a href="https://www.youtube.com/watch?v=we6poP0kw6E&index=27&list=PLWz5rJ2EKKc9CBxr3BVjPTPoDPLdPIFCE">무효화 레이아웃 및 성능</a> 비디오를 참조하십시오. 369 370 371</p> 372 373 374<h3 id="collection-window">상태 수집 창 제어</h3> 375 376<p> 377 Framestats와 단순한 프레임 타이밍은 양쪽 모두 아주 짧은 시간 범위 동안 데이터를 수집합니다. 렌더링 약 2초에 상당하는 시간입니다. 378 이 시간 범위를 정확하게 제어하려면(예: 데이터를 특정 애니메이션에 제한), 카운터를 모두 초기화한 다음 수집한 통계를 집계하면 됩니다. 379 380 381</p> 382 383<pre> 384>adb shell dumpsys gfxinfo <PACKAGE_NAME> reset 385</pre> 386 387<p> 388 이 방법은 명령 자체를 덤프하는 방법과 함께 써서 정기적인 간격을 두고 수집과 초기화를 반복하여 계속해서 2초 미만의 프레임 창을 캡처하도록 하는 데 쓰일 수도 있습니다. 389 390 391</p> 392 393 394<h3 id="diagnose">성능 저하 진단</h3> 395 396<p> 397 성능이 저하된 것을 알아내는 것은 문제를 추적하고 애플리케이션의 건강 상태를 높은 수준으로 유지 관리하는 데 좋은 첫 단계입니다. 398 그러나 dumpsys는 문제의 존재 여부와 상대적인 심각도만 식별하는 데 그치지 않습니다. 399 각 성능 문제의 제각기 다른 원인을 진단하고 이를 해결하기 위해 적절한 방법을 찾아야 하는 것은 변하지 않습니다. 400 이를 위해, <a href="{@docRoot}tools/help/systrace.html">systrace</a> 도구를 사용하는 것을 적극적으로 추천합니다. 401 402</p> 403 404 405<h3 id="resources">추가 리소스</h3> 406 407<p> 408 Android의 렌더링 파이프라인의 작동 원리나 여기에서 마주칠 수 있는 보편적인 문제와 그 해결 방법에 대한 자세한 정보를 원하시면, 다음 리소스 중 몇 가지를 유용하게 쓸 수 있습니다. 409 410 411</p> 412 413<ul> 414 <li>렌더링 성능의 기초 415 </li> 416 <li>왜 60fps일까요? 417 </li> 418 <li>Android UI와 GPU 419 </li> 420 <li>무효화 레이아웃 및 성능 421 </li> 422 <li>Systrace로 UI 성능 분석하기 423 </li> 424</ul> 425 426 427<h2 id="automate">UI 성능 테스트 자동화</h2> 428 429<p> 430 UI 성능 테스트에 대한 한 가지 관점은 그저 인간 테스터가 대상 앱에서 일련의 사용자 작업을 수행하도록 하는 것입니다. 그러면서 육안으로 jank가 있는지 살펴보든가, 아니면 오랜 시간을 들여 도구 중심적인 관점으로 jank를 찾아내는 것입니다. 431 432 하지만 이와 같은 수동식 방법은 위험 투성이입니다. 프레임 속도 변화를 인지하는 사람의 능력에는 개인차가 극명하고, 시간도 오래 걸릴 뿐더러 지루하고 오류가 발생할 가능성이 높습니다. 433 434 435</p> 436 437<p> 438 보다 효율적인 접근 방식은 자동화된 UI 테스트로부터 가져온 주요 성능 메트릭을 기록하고 분석하는 것입니다. 439 Android M 개발자 미리 보기에는 새로운 로깅 기능이 포함되어 있어 애플리케이션 애니메이션의 jank의 양과 심각도를 판별하기 쉽고, 이를 사용해 현재 성능을 판단하고 앞으로의 성능 목표를 추적하기 위해 철저한 프로세스를 구축할 수도 있습니다. 440 441 442 443</p> 444 445<p> 446 이 글에서는 그러한 데이터를 사용하여 성능 테스트를 자동화하는 데 권장되는 방안을 찬찬히 알려드립니다. 447 448</p> 449 450<p> 451 이것은 주로 두 가지 주요 작업으로 나뉘어 있습니다. 첫째로 무엇을 테스트할지, 어떻게 테스트할지를 확인합니다. 그런 다음 두 번째로 자동화된 테스트 환경을 설정하고 유지 관리하는 것입니다. 452 453 454</p> 455 456 457<h3 id="ui-tests">UI 테스트 설정</h3> 458 459<p> 460 자동화된 테스트를 시작하기 전에 우선 몇 가지 수준 높은 결정을 내려야 합니다. 그래야 테스트 공간과 스스로에게 필요한 부분을 제대로 숙지할 수 있습니다. 461 462</p> 463 464<h4> 465 테스트할 주요 애니메이션/흐름 알아내기 466</h4> 467 468<p> 469 성능이 불량한 것이 사용자에게 가장 눈에 띄는 것은 애니메이션이 원활히 작동하지 않을 때라는 점을 명심하십시오. 470 따라서, 테스트할 UI 작업 유형을 식별할 때에는 사용자가 가장 많이 접하게 되는 애니메이션이나 사용자 환경에 가장 중요한 것에 주안점을 두면 유용합니다. 471 472 예를 들어 다음은 이처럼 식별하는 데 유용하게 쓰일 수 있는 몇 가지 보편적인 시나리오입니다. 473</p> 474 475<ul> 476 <li>기본 ListView 또는 RecyclerView를 스크롤링 477 </li> 478 479 <li>비동기 대기 주기 동안 표시되는 애니메이션 480 </li> 481 482 <li>비트맵 로딩/조작이 들어 있을 수 있는 모든 애니메이션 483 </li> 484 485 <li>알파 혼합이 포함된 애니메이션 486 </li> 487 488 <li>Canvas로 사용자 지정 보기 드로잉 489 </li> 490</ul> 491 492<p> 493 팀 구성원인 엔지니어, 디자이너와 제품 관리자와 협력하여 이와 같이 테스트 대상 범위에 넣어야 하는 주요 제품 애니메이션의 우선 순위를 지정하십시오. 494 495</p> 496 497<h4> 498 앞으로의 목표를 정의하고 그것을 추적하기 499</h4> 500 501<p> 502 레벨이 높을 때에는 특정한 성능 목표를 알아내고 테스트 작성에 집중하며, 그에 관한 데이터를 수집하는 것이 매우 중요할 수 있습니다. 503 예를 들면 다음과 같습니다. 504</p> 505 506<ul> 507 <li>처음에만 UI 성능을 추적하여 좀 더 자세히 알아보기만 했으면 합니까? 508 </li> 509 510 <li>앞으로 마주치게 될 성능 저하를 방지하고자 합니까? 511 </li> 512 513 <li>지금은 매끄러운 프레임 비율이 약 90% 정도이지만 이번 사분기 내에 98%까지 올리고자 합니까? 514 </li> 515 516 <li>지금 매끄러운 프레임이 약 98%이고 성능이 저하되지 않기를 바랍니까? 517 </li> 518 519 <li>저사양 기기에서 성능을 개선하는 것이 목표입니까? 520 </li> 521</ul> 522 523<p> 524 이 모든 경우, 애플리케이션의 여러 버전에 걸쳐 성능을 나타내주는 사용 기록 추적을 수행하는 것이 좋습니다. 525 526</p> 527 528<h4> 529 테스트할 기기 정하기 530</h4> 531 532<p> 533 애플리케이션의 성능은 어느 기기에서 실행되는지에 따라 여러 가지로 달라집니다. 메모리 용량이 적고 GPU 파워가 딸리거나 CPU 칩 속도가 느린 기기도 있습니다. 534 이는 즉 한 가지 하드웨어 세트에서는 잘 작동하는 애니메이션이 다른 곳에서는 그렇지 않을 수도 있다는 뜻입니다. 더 나쁜 경우로는 파이프라인의 서로 다른 부분에서 병목 현상이 일어나는 결과를 초래할 수도 있습니다. 535 536 따라서, 사용자가 볼 수도 있는 이러한 변형을 감안하기 위해 테스트를 실행할 기기를 여러 가지로 선택하는 것이 중요합니다. 최신 고사양 기기, 저사양 기기, 태블릿 등 양쪽 측면을 모두 고려하십시오. 537 538 CPU 성능, RAM, 화면 밀도, 크기 등의 변형을 잘 살피십시오. 539 고사양 기기를 통과하는 테스트가 저사양 기기에서는 실패할 수도 있습니다. 540 541</p> 542 543<h4> 544 UI 테스트의 기본 프레임워크 545</h4> 546 547<p> 548 <a href="{@docRoot}training/testing/ui-testing/uiautomator-testing.html">UI Automator</a>와 <a href="{@docRoot}training/testing/ui-testing/espresso-testing.html">Espresso</a> 등의 도구 스위트는 개발자의 애플리케이션을 통과하는 사용자의 동작을 자동화하는 데 도움이 되도록 구축된 것입니다. 549 550 이들은 단순한 프레임워크로, 사용자와 기기의 상호작용을 흉내 냅니다. 551 이러한 프레임워크를 사용하려면, 사실상 개발자가 나름의 고유한 스크립트를 생성해야 합니다. 이는 일련의 사용자-동작을 통해 실행되고, 이를 기기 자체에서 재생합니다. 552 553 554</p> 555 556<p> 557 이렇게 자동화된 테스트를 여러 가지로 조합하여 <code>dumpsys gfxinfo</code>와 함께 사용하면 재현 가능한 시스템을 재빨리 만들어내 테스트를 실행하고 해당 조건 하에서 성능 정보를 측정할 수 있습니다. 558 559 560</p> 561 562 563<h3 id="automated-tests">자동화된 UI 테스트 설정</h3> 564 565<p> 566 UI 테스트를 실행할 수 있게 되고, 한 번의 테스트로부터 데이터를 수집할 파이프라인을 갖추게 되면 다음으로 중요한 단계는 해당 테스트를 여러 번, 여러 기기에 걸쳐 실행하고 그 결과 도출된 성능 데이터를 집계하여 개발 팀이 한층 더 상세하게 분석할 수 있게 해주는 프레임워크를 채택하는 것입니다. 567 568 569 570</p> 571 572<h4> 573 테스트 자동화를 위한 프레임워크 574</h4> 575 576<p> 577 UI 테스트 프레임워크(예: <a href="{@docRoot}training/testing/ui-testing/uiautomator-testing.html">UI Automator</a>)는 대상 기기/에뮬레이터에서 직접 실행된다는 점에 주목할 만한 가치가 있습니다. 578 반면 <em>dumpsys gfxinfo</em>에 의해 완료되는 성능 수집 정보는 호스트 머신이 구동하여 ADB를 통해 명령을 전송합니다. 579 이러한 각각의 항목 자동화를 연결하는 데 도움을 주기 위해 <a href="{@docRoot}tools/help/monkeyrunner_concepts.html">MonkeyRunner</a> 프레임워크가 개발되었습니다. 이것은 호스트 머신에서 실행되는 스크립팅 시스템으로, 일련의 연결된 기기에 명령을 발행하기도 하고 이들로부터 데이터를 수신할 수도 있습니다. 580 581 582 583</p> 584 585<p> 586 UI 성능 테스트를 제대로 자동화하기 위해 최소한의 수준으로 일련의 스크립트를 구축하는 경우, 다음과 같은 작업을 수행하기 위해 monkeyRunner를 활용할 수 있어야 합니다. 587 588</p> 589 590<ul> 591 <li>원하는 APK를 대상 기기(하나 이상일 수 있음) 또는 에뮬레이터에 로드하여 시작합니다. 592 </li> 593 594 <li>UI Automator UI 테스트를 시작하고 실행되도록 허용하십시오. 595 </li> 596 597 <li><em>dumpsys gfxinfo</em><em></em>를 통해 성능 정보를 수집합니다. 598 </li> 599 600 <li>정보를 집계하고 이를 다시 유용한 방식으로 표시해 개발자에게 보여줍니다. 601 </li> 602</ul> 603 604 605<h3 id="triage">관측된 문제 심사 및 수정</h3> 606 607<p> 608 문제의 패턴이나 성능 저하를 확인했으면, 다음 단계는 해결 방법을 알아내어 적용합니다. 609 자동화된 테스트 프레임워크가 프레임에 대해 정확한 타이밍 분석을 유지하는 경우, 최근의 의심스러운 코드/레이아웃 변경 내용을 꼼꼼히 훑어보거나(성능 저하의 경우) 수동 조사로 전환했을 때 시스템의 어느 부분을 분석할지 범위를 좁히는 데 도움이 될 수 있습니다. 610 611 612 수동 조사의 경우, <a href="{@docRoot}tools/help/systrace.html">systrace</a>부터 시작하는 것이 좋습니다. 이렇게 하면 렌더링 파이프라인의 모든 단계, 시스템에 있는 모든 스레드와 코어는 물론 개발자가 정의한 사용자 지정 이벤트 마커 일체에 대해 정확한 타이밍 정보를 나타내주기 때문입니다. 613 614 615</p> 616 617<h4> 618 임시 타이밍을 적절하게 프로파일링하기 619</h4> 620 621<p> 622 렌더링 성능에서 타이밍을 가져와 이를 측정하는 데 수반되는 몇 가지 어려움을 알아두는 것이 중요합니다. 623 이와 같은 숫자는 본래 결정적인 것이 아니고 시스템 상태, 이용 가능한 메모리 용량, 열 제한 및 개발자가 사는 지역에 태양 플레어가 마지막으로 영향을 미친 시점 등에 따라 변동폭이 큽니다. 624 625 요점은 같은 테스트를 두 번 실행하면서 서로 근사치이지만 완전히 똑같지는 않은, 약간 다른 숫자를 얻어내는 데 있습니다. 626 627 628</p> 629 630<p> 631 이런 식으로 데이터를 제대로 수집하고 프로파일링한다는 것은 같은 테스트를 여러 번 거듭 실행하면서 얻어지는 결과를 평균 또는 중간값(너무 복잡해지니 이것을 '배치(batch)'라고 부르기로 합시다)으로 누적한다는 것을 뜻합니다. 이렇게 하면 테스트 성과를 대략적으로 어림잡을 수 있으면서 정확한 타이밍은 없어도 됩니다. 632 633 634 635</p> 636 637<p> 638 이러한 배치를 코드 변경 사이사이에 사용하여 그러한 변경 내용이 성능에 미치는 상대적인 영향을 알아볼 수도 있습니다. 639 변경 전 배치의 평균 프레임 속도가 변경 후 배치에서보다 빠른 경우, 해당 변경에 대해 전반적으로 좋은 WRT 성능을 성취했다는 뜻입니다. 640 641 642</p> 643 644<p> 645 이는 즉 개발자가 수행하는 자동화된 UI 테스트는 모두 이 개념을 감안해야 한다는 뜻이기도 하고, 테스트 중에 일어나는 모든 변칙적인 부분 또한 감안해야 한다는 뜻입니다. 646 예를 들어 애플리케이션 성능이 일종의 기기 문제(본인의 애플리케이션에서 기인한 것이 아님) 때문에 갑자기 뚝 떨어지는 경우라면 해당 배치를 다시 실행하여 조금 덜 혼란스러운 타이밍을 얻어야 할 수도 있습니다. 647 648 649 650</p> 651 652<p> 653 그렇다면 측정값이 의의를 지니려면 테스트를 몇 번이나 수행하는 것이 좋습니까? 최소한 10번은 해야 합니다. 실행 횟수가 50이나 100처럼 커질수록 더욱 정확한 경과를 도출할 수 있습니다(물론, 이제는 정확도와 시간을 맞바꿔야 하는 셈입니다). 654 655 656</p> 657