ユニットテストでDrawable画像が表示されているかを確認したい時ってあんまり無いのでしょうか。Googleから公式で用意されていないようなのでEspressoの時は自作でDrawableMatcherを作って対応していました。Composeだとどうなんだろうと調べてみるとSemanticsというのを使うらしい。

https://developer.android.com/jetpack/compose/semantics?hl=ja

「テスト フレームワークは、このプロパティを使用してノードを検出し、それを操作して、アサーションを行います。」

一応Semantics自体はテストフレームワークのプロパティを設定してアサーションしても良いことは書いてありました。Semanticsを使うとModifierの属性を追加できるようなのでImageComposeにDrawableリソースを保存できるようにします。

build.gradle.ktsに下記を追加。

implementation("androidx.compose.ui:ui-test-junit4:2.6.2") // バージョンは適宜調べてください

下記のコードを追加。

import androidx.compose.ui.semantics.SemanticsPropertyKey
import androidx.compose.ui.semantics.SemanticsPropertyReceiver
import androidx.compose.ui.test.SemanticsMatcher
import androidx.compose.ui.test.SemanticsNodeInteraction
import androidx.compose.ui.test.junit4.ComposeContentTestRule

val DrawableId = SemanticsPropertyKey<Int>("DrawableResId")
var SemanticsPropertyReceiver.drawableId by DrawableId
fun ComposeContentTestRule.onNodeWithDrawable(drawableId: Int): SemanticsNodeInteraction =
    onNode(SemanticsMatcher.expectValue(DrawableId, drawableId))

ImageComposeに画像を設定します。

Image(
    modifier = Modifier.semantics { drawableId = R.drawable.ic_app },
    painter = painterResource(id = R.drawble.ic_app),
    contentDescription = stringResource(id = R.string.app_name)
)

ユニットテストでonNodeWithDrawable()を使ってアサーションします。

@RunWith(AndroidJUnit4::class)
class ImageComposeTest {
    @get:Rule
    val composeRule = createComposeRule()

    @Test
    fun assert_image() {
        composeRule.setContent {
            // Imageを表示するCompose
      }
    composeRule.onNodeWithDrawable(R.drawable.ic_app).assertIsDisplayed()
    }
}

https://stackoverflow.com/a/71389302

これでImageComposeがDrawableリソースのsemanticsを持っているか確認できるが、painterと同じ設定をしてしまっているし、ImageComposeのcontentDescriptionはnullableであるが設定するべきで、contentDescriptionのアサーションをすれば実質同じことなので、なんかテストとしては微妙なのかなと思います。公式でonNodeWithDrawable()を作ってくれないかなぁ。