MST

星途 面试题库

面试题:Kotlin Android UI测试中处理异步操作

在Kotlin编写的Android UI测试中,遇到需要等待一个异步任务完成(例如网络请求获取数据并更新UI)的场景,使用什么方法来确保测试等待异步任务完成后再进行断言?请举例说明使用不同的等待策略(如IdlingResource、Espresso的默认等待机制等)来处理这种情况。
13.2万 热度难度
编程语言Kotlin

知识考点

AI 面试

面试题答案

一键面试

使用IdlingResource

  1. 定义IdlingResource: 假设我们有一个网络请求的异步任务,在ViewModel中发起。首先定义一个CountingIdlingResource
class NetworkIdlingResource {
    companion object {
        private const val RESOURCE = "NETWORK"
        val idlingResource: CountingIdlingResource = CountingIdlingResource(RESOURCE)
    }
}
  1. 在异步任务中控制IdlingResource: 在发起网络请求前调用idlingResource.increment(),请求完成后调用idlingResource.decrement()。例如在ViewModel中:
class MyViewModel : ViewModel() {
    init {
        NetworkIdlingResource.idlingResource.increment()
        viewModelScope.launch {
            try {
                // 模拟网络请求
                delay(2000)
                // 网络请求成功处理
            } catch (e: Exception) {
                // 网络请求失败处理
            } finally {
                NetworkIdlingResource.idlingResource.decrement()
            }
        }
    }
}
  1. 在测试中注册IdlingResource
@RunWith(AndroidJUnit4::class)
class MyUITest {
    @get:Rule
    val activityScenarioRule = ActivityScenarioRule(MyActivity::class.java)

    @Before
    fun registerIdlingResource() {
        Espresso.registerIdlingResources(NetworkIdlingResource.idlingResource)
    }

    @After
    fun unregisterIdlingResource() {
        Espresso.unregisterIdlingResources(NetworkIdlingResource.idlingResource)
    }

    @Test
    fun testAsyncTask() {
        onView(withId(R.id.some_view)).check(matches(isDisplayed()))
    }
}

使用Espresso的默认等待机制

Espresso有默认的等待机制,它会等待视图渲染完成。如果异步任务更新的视图在布局中,并且视图的状态变化是可见的(例如TextView的文本更新),可以直接使用Espresso的断言。

@RunWith(AndroidJUnit4::class)
class MyUITest {
    @get:Rule
    val activityScenarioRule = ActivityScenarioRule(MyActivity::class.java)

    @Test
    fun testAsyncTaskWithDefaultWait() {
        // 假设异步任务更新了一个TextView的文本
        onView(withId(R.id.text_view)).check(matches(withText("Expected Text")))
    }
}

Espresso会在一定时间内(默认超时时间为1000毫秒)等待视图达到预期状态。如果需要自定义等待时间,可以使用ViewInteraction.pollingTimeout方法。

@Test
fun testAsyncTaskWithCustomTimeout() {
    onView(withId(R.id.text_view))
      .pollingTimeout(3000)
      .check(matches(withText("Expected Text")))
}