Robolectric에서 Snackbar의 동작을 테스트하는 방법은 무엇인가요?
_____A1: 네, Robolectric은 Android UI 컴포넌트를 JVM 환경에서 실행할 수 있도록 해주므로 Snackbar 동작도 테스트할 수 있습니다. 다만 Snackbar는 내부적으로 `Handler`와 `Looper`를 사용하고, UI 스레드에서 실행되어야 하므로 이를 고려한 테스트 작성이 필요합니다.
---
Q2: Snackbar가 정상적으로 표시되었는지 Robolectric에서 어떻게 확인하나요?
A2: Snackbar는 기본적으로 `Snackbar.SnackbarLayout`이라는 View를 포함하는 뷰 계층에 추가됩니다. 다음과 같은 방법으로 확인할 수 있습니다:
```java
// 1. Snackbar 생성 및 표시
Snackbar snackbar = Snackbar.make(parentView, "Hello, Snackbar!", Snackbar.LENGTH_SHORT);
snackbar.show();
// 2. Root 뷰에서 SnackbarLayout 확인
ViewGroup rootView = (ViewGroup) parentView.getRootView();
Snackbar.SnackbarLayout snackbarLayout = null;
for (int i = 0; i < rootView.getChildCount(); i++) {
View child = rootView.getChildAt(i);
if (child instanceof Snackbar.SnackbarLayout) {
snackbarLayout = (Snackbar.SnackbarLayout) child;
break;
}
}
// 3. Snackbar가 화면에 있는지 검증
assertNotNull(snackbarLayout);
// 4. 텍스트 내용 확인
TextView textView = snackbarLayout.findViewById(com.google.android.material.R.id.snackbar_text);
assertEquals("Hello, Snackbar!", textView.getText().toString());
```
---
Q3: Snackbar의 메시지 텍스트를 검증하는 올바른 방법은?
A3: Snackbar는 내부에 `snackbar_text`라는 ID를 가진 `TextView`를 포함합니다. SnackbarLayout에서 해당 뷰를 찾아 텍스트를 추출할 수 있습니다. (위 코드의 4번 참조)
---
Q4: Snackbar가 정상적으로 사라지는지 테스트하려면 어떻게 해야 하나요?
A4: `Snackbar.LENGTH_SHORT`나 `Snackbar.LENGTH_LONG` 같이 시간이 지정된 Snackbar는 일정 시간이 지나면 자동으로 사라집니다. Robolectric에서는 `ShadowLooper`를 사용하여 시간 경과를 시뮬레이트할 수 있습니다.
```java
// Snackbar 표시
// 시간 경과 전
assertNotNull(findSnackbarLayout(rootView));
// ShadowLooper 실행
ShadowLooper.runUiThreadTasksIncludingDelayedTasks();
// 시간 경과 후
assertNull(findSnackbarLayout(rootView));
```
`findSnackbarLayout()`은 앞서 설명한 SnackbarLayout을 찾는 헬퍼 메서드입니다.
---
Q5: Snackbar의 행동(UI의 동작 외 이벤트 처리)을 테스트하려면?
A5: 예를 들어, Snackbar의 "확인" 버튼 클릭 같은 인터랙션이 있다면 `setAction`의 `OnClickListener`를 직접 호출하고 그 결과를 검증할 수 있습니다.
```java
AtomicBoolean clicked = new AtomicBoolean(false);
Snackbar snackbar = Snackbar.make(parentView, "Message", Snackbar.LENGTH_INDEFINITE);
snackbar.setAction("확인", v -> clicked.set(true));
snackbar.show();
Snackbar.SnackbarLayout snackbarLayout = findSnackbarLayout(parentView.getRootView());
TextView actionView = snackbarLayout.findViewById(com.google.android.material.R.id.snackbar_action);
actionView.performClick();
assertTrue(clicked.get());
```
---
Q6: Robolectric에서 Snackbar 테스트 시 유의사항은?
A6:
- `Snackbar.show()`는 내부적으로 비동기적으로 동작하므로 `ShadowLooper.runUiThreadTasksIncludingDelayedTasks()`를 호출하여 관련 작업을 실행시켜야 결과를 확실히 볼 수 있습니다.
- Material Components 라이브러리와 호환되는 Robolectric 버전을 사용해야 합니다.
- 뷰 계층에서 SnackbarLayout을 정확히 찾아내는 헬퍼 메서드 구현이 중요합니다.
---
요약:
Robolectric에서 Snackbar를 테스트할 때는 Snackbar를 띄운 뒤 루트 뷰에서 `Snackbar.SnackbarLayout`을 찾아내고, 내부 텍스트나 액션 뷰를 활용해 메시지나 버튼 클릭 여부를 검증합니다. `ShadowLooper`를 통해 시간 지연 및 UI 스레드 작업 처리를 시뮬레이트해야 하고, 필요한 경우 액션 클릭을 직접 트리거하여 관련 동작을 테스트할 수 있습니다.
Snackbar는 `CoordinatorLayout` 위에 `BaseTransientBottomBar`를 이용해 동적으로 뷰를 추가하고, 애니메이션과 타이머에 의해 자동으로 사라지는 특성이 있어서, 이를 그대로 테스트 프레임워크에서 재현하기 위해 몇 가지 고려할 점이 있습니다.
다음은 Robolectric 환경에서 Snackbar 동작을 효과적으로 테스트하는 방법과 팁입니다.
1. 기본적으로 Snackbar가 보여지는지 확인하기 Snackbar는 내부적으로 `Snackbar.SnackbarLayout` 뷰를 생성하여 현재 액티비티나 프래그먼트의 뷰 위에 추가합니다.
Robolectric에서는 뷰 계층 구조를 직접 탐색하여 이 뷰가 존재하는지 확인하는 방법으로 동작을 검증할 수 있습니다.
```java // 의존뷰는 예를 들어 CoordinatorLayout이나 단순 View View parentView = activity.findViewById(R.id.coordinator_layout); // Snackbar 생성 및 보여주기 Snackbar snackbar = Snackbar.make(parentView, "Test Snackbar", Snackbar.LENGTH_SHORT); snackbar.show(); // Robolectric 스케줄러 실행: 애니메이션 및 핸들러 메시지 진행 Robolectric.flushForegroundThreadScheduler(); // 뷰 계층에서 SnackbarLayout을 찾음 ViewGroup rootView = (ViewGroup) parentView.getRootView(); boolean snackbarFound = false; for (int i = 0; i < rootView.getChildCount(); i++) { View child = rootView.getChildAt(i); if (child instanceof Snackbar.SnackbarLayout) { snackbarFound = true; break; } } // 검증 assertTrue(snackbarFound); ``` 이처럼 Snackbar가 실제 뷰 트리에 추가되었는지 여부를 테스트할 수 있습니다.
---
2. 텍스트 내용, 행동 버튼 등 Snackbar 내부 UI 확인하기 Snackbar 내부의 텍스트 `TextView`나 버튼 `Button`을 찾아 내용 검증도 가능합니다.
```java Snackbar.SnackbarLayout snackbarLayout = (Snackbar.SnackbarLayout) rootView.getChildAt(indexOfSnackbar); TextView textView = snackbarLayout.findViewById(com.google.android.material.R.id.snackbar_text); assertEquals("Test Snackbar", textView.getText().toString()); Button actionButton = snackbarLayout.findViewById(com.google.android.material.R.id.snackbar_action); assertEquals("RETRY", actionButton.getText().toString()); ``` 이렇게 텍스트와 액션이 올바르게 셋팅되었는지 확인할 수 있습니다.
---
3. Snackbar 애니메이션, 타이머 동작 테스트 Snackbar는 `LENGTH_SHORT`, `LENGTH_LONG` 등에 따라 자동으로 사라지지만, Robolectric에서는 기본적으로 이런 타이머나 애니메이션이 즉시 처리되지 않습니다.
따라서 아래 단계를 활용합니다.
- `Robolectric.flushForegroundThreadScheduler()` 또는 `Robolectric.getForegroundThreadScheduler().advanceToLastPostedRunnable()` 호출해 타이머 핸들러를 실행합니다.
- 이를 통해 스낵바가 자동으로 사라지는 이벤트를 처리하고, 뷰가 제거되는 상황을 시뮬레이션할 수 있습니다.
예) ```java snackbar.show(); // 타이머가 동작하여 Snackbar가 사라져야 하는 시점까지 진행 Robolectric.getForegroundThreadScheduler().advanceBy(3500, TimeUnit.MILLISECONDS); // 이제 뷰 트리에서 SnackbarLayout이 사라졌는지 확인 boolean snackbarExists = false; for (int i = 0; i < rootView.getChildCount(); i++) { if (rootView.getChildAt(i) instanceof Snackbar.SnackbarLayout) { snackbarExists = true; break; } } assertFalse(snackbarExists); ``` ---
4. 액션 버튼 클릭 테스트 Snackbar에 설정한 액션 버튼 클릭도 테스트 가능하며, 이를 위해 액션 버튼을 찾아서 `performClick()` 호출하면 됩니다.
```java Button actionButton = snackbarLayout.findViewById(com.google.android.material.R.id.snackbar_action); assertNotNull(actionButton); // 액션이 정상 등록되었는지, AtomicBoolean clicked = new AtomicBoolean(false); snackbar.setAction("RETRY", v -> clicked.set(true)); actionButton.performClick(); assertTrue(clicked.get()); ``` 액션 람다가 정상 실행되는지 확인할 수 있습니다.
---
5. 팁 및 주의사항 - `Snackbar.make()`에 전달하는 뷰는 현재 화면에 표시된 뷰 계층에 있어야 동작이 정확합니다.
- Robolectric의 특정 버전에서는 Material Components 라이브러리와의 호환성 문제로 Snackbar 구현이 다를 수 있으므로, 라이브러리 버전과 Robolectric 버전을 맞춰 사용하는 것이 좋습니다.
- 애니메이션 관련 처리를 위해서 Robolectric의 스케줄러 제어를 잘 활용해야 합니다.
- 테스트가 매우 까다로운 경우, Snackbar 노출 여부를 검증하는 대신 비즈니스 로직에서 Snackbar 호출 여부를 간접적으로 확인하도록 리팩토링할 수도 있습니다.
--- 요약 Robolectric에서 Snackbar 동작 테스트는 다음과 같습니다: 1. `Snackbar.show()` 호출 후 뷰 트리에 `Snackbar.SnackbarLayout` 존재 여부 확인.
2. Snackbar 내부 텍스트, 액션 버튼 텍스트 등을 UI 트리에서 찾아 검증.
3. Robolectric 스케줄러로 타이머와 애니메이션을 진행시켜 자동 사라짐 동작 확인.
4. 액션 버튼 클릭 시 리스너가 올바르게 동작하는지 `performClick()`으로 테스트.
5. 필요 시 테스트 환경에 맞게 라이브러리 버전과 스케줄러 동작을 조정. 이 과정을 거치면 Robolectric에서도 Snackbar UI와 동작을 적절히 검증할 수 있습니다.
작성자:
이현서 [비회원]
| 작성일자: 1년 전
2025-05-26 03:51:20
조회수: 145 | 댓글: 0 | 좋아요: 0 | 싫어요: 0
조회수: 145 | 댓글: 0 | 좋아요: 0 | 싫어요: 0
내용이 부정확하다면 싫어요를 클릭해주세요.