UI 테스트에서 다음과 같은 테스트가 필요할 때가 있습니다.
- 어떤 이벤트가 발생되었을 때 ImageView의 Source 즉 Drawable이 변경되었는지 확인
위 경우와 같은 ImageView의 테스트는 Espresso 라이브러리가 지원해지지 않기 때문에 아래와 같은 유틸 클래스가 필요합니다.
import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.drawable.Drawable
import android.view.View
import android.widget.ImageView
import org.hamcrest.Description
import org.hamcrest.TypeSafeMatcher
class DrawableMatcher internal constructor(private val expectedId: Int) :
TypeSafeMatcher<View?>(View::class.java) {
private var resourceName: String? = null
override fun matchesSafely(target: View?): Boolean {
if (target !is ImageView) {
return false
}
val imageView = target
if (expectedId == EMPTY) {
return imageView.drawable == null
}
if (expectedId == ANY) {
return imageView.drawable != null
}
val resources = target.getContext().resources
val expectedDrawable = resources.getDrawable(
expectedId
)
resourceName = resources.getResourceEntryName(expectedId)
if (expectedDrawable == null) {
return false
}
val bitmap = getBitmap(imageView.drawable)
val otherBitmap = getBitmap(expectedDrawable)
return bitmap.sameAs(otherBitmap)
}
private fun getBitmap(drawable: Drawable): Bitmap {
val bitmap = Bitmap.createBitmap(
drawable.intrinsicWidth,
drawable.intrinsicHeight,
Bitmap.Config.ARGB_8888
)
val canvas = Canvas(bitmap)
drawable.setBounds(0, 0, canvas.width, canvas.height)
drawable.draw(canvas)
return bitmap
}
override fun describeTo(description: Description) {
description.appendText("with drawable from resource id: ")
description.appendValue(expectedId)
if (resourceName != null) {
description.appendText("[")
description.appendText(resourceName)
description.appendText("]")
}
}
companion object {
const val EMPTY = -1
const val ANY = -2
}
}
object EspressoTestsMatchers {
fun withDrawable(resourceId: Int): DrawableMatcher {
return DrawableMatcher(resourceId)
}
fun noDrawable(): DrawableMatcher {
return DrawableMatcher(DrawableMatcher.EMPTY)
}
fun hasDrawable(): DrawableMatcher {
return DrawableMatcher(DrawableMatcher.ANY)
}
}
그 다음 아래와 같이 테스트파일을 작성해서 테스트 할 수 있습니다.
@RunWith(AndroidJUnit4::class)
class FlashlightActivityTest {
@Rule
@JvmField
val activityRule = ActivityScenarioRule(
FlashlightActivity::class.java
)
@Test
fun testFlashlightButtonVisibility() {
Espresso.onView(ViewMatchers.withId(R.id.flashlightButton))
.check(ViewAssertions.matches(ViewMatchers.isDisplayed()));
}
@Test
fun testFlashlightButtonToggle() {
val scenario = activityRule.scenario
var viewModel: FlashlightViewModel? = null
scenario.onActivity { activity ->
viewModel = ViewModelProvider(activity).get(FlashlightViewModel::class.java)
}
viewModel?.turnOffFlashlight()
onView(withId(R.id.flashlightButton)).check(matches(withDrawable(R.drawable.off_button)));
}
}
위 테스트의 testFlashlightButtonToggle()에서 viewModel을 이용해서 ImageView의 Source가 변경되었는지 확인할 수 있습니다.
https://medium.com/@dbottillo/android-ui-test-espresso-matcher-for-imageview-1a28c832626f
https://devtut.github.io/android/testing-ui-with-espresso.html#espresso-simple-ui-test
'Android > UI Test' 카테고리의 다른 글
[Android] UI 테스트 -1 (0) | 2023.09.26 |
---|---|
[Android] UI 테스트란? (0) | 2023.09.26 |