Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Espresso does not wait for AndroidX's ListAdapter's by default #382

Open
matejdro opened this issue Jun 7, 2019 · 1 comment
Open

Espresso does not wait for AndroidX's ListAdapter's by default #382

matejdro opened this issue Jun 7, 2019 · 1 comment

Comments

@matejdro
Copy link

matejdro commented Jun 7, 2019

Description

Included androidx.recyclerview.widget.ListAdapter performs asynchronous operations in the background. However, Espresso does not appear to be aware of it and thus tests can fail if async list diff is still diffing while Espresso starts inspecting views.

Steps to Reproduce

  1. Download RecyclerTest.zip
  2. Run ExampleInstrumentedTest couple of times, at least one test will fail eventually

Expected Results

Espresso should wait for built-in ListAdapter to finish diffing

Actual Results

Espresso does not wait and can fail the test

@MichalDanielDobrzanski
Copy link

MichalDanielDobrzanski commented Jan 13, 2022

How come it is not resolved yet?

In the meantime I have managed to make a custom solution for it:

/**
 * A solution for espresso execution to perform diffs on MainThread
 */
abstract class ThreadedListAdapter<T, VH : RecyclerView.ViewHolder>(
    itemCallback: DiffUtil.ItemCallback<T>
) :
    ListAdapter<T, VH>(
        AsyncDifferConfig.Builder(itemCallback)
            .apply {
                if (isEspresso()) setBackgroundThreadExecutor(MainThreadExecutor())
            }
            .build()
    )

/**
 *  This is a fork of internal MainThreadExecutor from [AsyncListDiffer]
 */
private class MainThreadExecutor : Executor {
    val mHandler = Handler(Looper.getMainLooper())
    override fun execute(command: Runnable) {
        mHandler.post(command)
    }
}

fun isEspresso(): Boolean {
    return try {
        Class.forName("androidx.test.espresso.Espresso")
        true
    } catch (e: ClassNotFoundException) {
        false
    }
}

and in the tests call:

InstrumentationRegistry.getInstrumentation().waitForIdleSync()

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants