본문 바로가기
Android/UI Test

[Android] UI 테스트 -2

by startSW 2023. 9. 26.

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

 

Android UI Test — Espresso Matcher for ImageView

EDIT: this post has been update to support Vector drawables, thanks to Enrico Gueli

medium.com

 

https://devtut.github.io/android/testing-ui-with-espresso.html#espresso-simple-ui-test

 

Android - Testing UI with Espresso

Espresso simple UI test, Overall Espresso, Open Close DrawerLayout , Set Up Espresso, Performing an action on a view, Finding a view with onView, Create Espresso Test Class, Up Navigation, Espresso custom matchers, Group a collection of test classes in a t

devtut.github.io

 

'Android > UI Test' 카테고리의 다른 글

[Android] UI 테스트 -1  (0) 2023.09.26
[Android] UI 테스트란?  (0) 2023.09.26