Compose插桩测试用含空格反引号方法名触发R8版本兼容错误
问题
在Compose插桩测试中使用反引号定义包含空格的测试方法名时,编译触发错误;移除反引号和空格后测试可正常编译。
编译错误信息
Caused by: com.android.tools.r8.internal.Jj: com.android.tools.r8.internal.Jc: Space characters in SimpleName 'given a closebottomsheetevent eventlistener on close bottom sheet should be called' are not allowed prior to DEX version 040
测试代码示例
package com.dooitu.mobile.android.ui.homefeed import android.content.Context import androidx.activity.ComponentActivity import androidx.compose.runtime.State import androidx.compose.runtime.mutableStateOf import androidx.compose.ui.test.junit4.createAndroidComposeRule import com.dooitu.mobile.android.ui.homefeed.components.HomeFeedEvent import com.dooitu.mobile.android.ui.homefeed.models.HomeFeedScreenEventListener import com.dooitu.mobile.android.ui.theme.DooituTheme import org.junit.Rule import org.junit.Test import org.koin.androidx.compose.get class HomeFeedScreenTest { @get:Rule // Use a dummy activity instead of real MainActivity val composeTestRule = createAndroidComposeRule<ComponentActivity>() private var triggeredEventId: Int? = null private val eventListener = object : HomeFeedScreenEventListener { override fun onCloseBottomSheet() { triggeredEventId = ON_CLOSE_BOTTOM_SHEET_EVENT_ID } override fun onOpenComments(postId: String, numberOfComments: Int) { triggeredEventId = ON_OPEN_COMMENTS_EVENT_ID } override fun onOpenShare(shareLink: String, context: Context) { TODO("Not yet implemented") } override fun onOpenPostSingleView(postId: String) { TODO("Not yet implemented") } override fun onOpenPostActions(postId: String, userId: String) { TODO("Not yet implemented") } override fun onOpenPostDetails(postId: String) { TODO("Not yet implemented") } override fun onProfileImageClicked(userId: String, isCurrentUser: Boolean) { TODO("Not yet implemented") } } private val updateViewModel = HomeFeedUpdateViewModel() private fun startScenario(state: State<HomeFeedState>) { composeTestRule.setContent { DooituTheme.SurfaceContainer { HomeFeedScreen( state = state, viewModel = get(), cacheDataSourceFactory = get(), getReloadedPostFlow = updateViewModel::reloadedPost, eventsListener = eventListener, logScreenView = {} ) } } } @Test fun `given a closebottomsheetevent eventlistener on close bottom sheet should be called` () { val closeBottomSheetState = mutableStateOf( HomeFeedState( emptyList(), emptyList(), event = HomeFeedEvent.CloseBottomSheet ) ) // Start the app startScenario(closeBottomSheetState) assert(triggeredEventId == ON_CLOSE_BOTTOM_SHEET_EVENT_ID) } }
解决方案
原因说明
DEX版本低于040(对应Android 13/API 33)时,字节码不允许方法名包含空格。Kotlin中用反引号定义的带空格方法名,编译后会直接保留空格,因此触发R8的校验错误。
方案1:升级DEX版本至040及以上
在模块的build.gradle.kts(或build.gradle)中配置编译、目标SDK版本为33+,并指定DEX目标版本:
android { compileSdk = 33 targetSdk = 33 dexOptions { targetDexVersion = "040" } }
注意:升级targetSdk到33需要适配Android 13的权限及行为变更,需确认项目兼容性。
方案2:使用@DisplayName注解替代空格方法名
保持方法名符合Java字节码规范(无空格),同时通过@DisplayName注解设置测试报告中显示的友好名称:
import org.junit.jupiter.api.DisplayName // ... @Test @DisplayName("given a closebottomsheetevent eventlistener on close bottom sheet should be called") fun givenCloseBottomSheetEventEventListenerOnCloseBottomSheetShouldBeCalled() { val closeBottomSheetState = mutableStateOf( HomeFeedState( emptyList(), emptyList(), event = HomeFeedEvent.CloseBottomSheet ) ) startScenario(closeBottomSheetState) assert(triggeredEventId == ON_CLOSE_BOTTOM_SHEET_EVENT_ID) }
该方案无需升级SDK版本,兼容所有Android版本,同时测试报告仍能显示清晰的测试描述。
内容的提问来源于stack exchange,提问作者Nicola Gallazzi
相关产品推荐
相关产品推荐

