当前位置: 首页 > 知识库问答 >
问题:

Espresso不等待AsyncTask完成

卫昊东
2023-03-14

根据Espresso文档,检测测试应该自动等待AsyncTasks完成。但它不起作用。我创建了这个简单的测试用例:

package foo.bar;

import android.os.AsyncTask;
import android.support.test.annotation.UiThreadTest;
import android.support.test.filters.LargeTest;
import android.support.test.rule.UiThreadTestRule;
import android.support.test.runner.AndroidJUnit4;
import android.util.Log;

import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;

import static org.junit.Assert.assertEquals;

@RunWith(AndroidJUnit4.class)
@LargeTest
public class ExampleInstrumentedTest {

    private static final String TAG = "ExampleInstrumentedTest";

    @Rule public UiThreadTestRule uiThreadTestRule = new UiThreadTestRule();

    @Test
    @UiThreadTest
    public void testAsyncTask() throws Throwable {
        Log.d(TAG, "testAsyncTask entry");
        uiThreadTestRule.runOnUiThread(() -> new AsyncTask<String, Void, Integer>() {
            @Override
            protected Integer doInBackground(String... params) {
                Log.d(TAG, "doInBackground() called with: params = [" + params + "]");
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException ignored) {
                }
                return params.length;
            }

            @Override
            protected void onPostExecute(Integer integer) {
                Log.d(TAG, "onPostExecute() called with: integer = [" + integer + "]");
                assertEquals(3, (int) integer);
                throw new RuntimeException("this should fail the test");
            }
        }.execute("One", "two", "three"));
        Log.d(TAG, "testAsyncTask end");
    }
}

返回UI线程时测试应该失败,但它总是成功。这是测试的logcat输出:

I/TestRunner: started: testAsyncTask(foo.bar.ExampleInstrumentedTest)
D/ExampleInstrumentedTest: testAsyncTask entry
D/ExampleInstrumentedTest: testAsyncTask end
I/TestRunner: finished: testAsyncTask(foo.bar.ExampleInstrumentedTest)
D/ExampleInstrumentedTest: doInBackground() called with: params = [[Ljava.lang.String;@8da3e9]

正如您所看到的,测试在后台方法执行之前就已经完成了。我怎样才能让考试等待呢?

共有1个答案

云伯寅
2023-03-14

事实证明,Espresso确实会等待AsyncTasks完成,但前提是存在视图交互。

原因是Espresso在uicontroller#loopmainthreaduntilidle()方法期间等待任务,该方法在每次视图交互时都会在窗帘后面自动调用。因此,尽管我的测试不需要任何视图或活动,但我必须创建它们。

这就是工作测试现在的样子:

@RunWith(AndroidJUnit4.class)
@LargeTest
public class ExampleInstrumentedTest {

    private static final String TAG = "ExampleInstrumentedTest";

    @Rule public ActivityTestRule<TestingActivity> activityTestRule = new ActivityTestRule<>(
        TestingActivity.class, false, false);

    @Before
    public void setUp() throws Exception {
        activityTestRule.launchActivity(new Intent());
    }

    @Test
    public void testAsyncTask() throws Throwable {
        Log.d(TAG, "testAsyncTask entry");

        AsyncTask<String, Void, Integer> task = new AsyncTask<String, Void, Integer>() {

            @Override
            protected Integer doInBackground(String... params) {
                Log.d(TAG, "doInBackground() called with: params = [" + params + "]");
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException ignored) {
                }
                return params.length;
            }

            @Override
            protected void onPostExecute(Integer integer) {
                Log.d(TAG, "onPostExecute() called with: integer = [" + integer + "]");
                assertEquals(3, (int) integer);
                throw new RuntimeException("this should fail the test");
            }
        };
        task.execute("One", "two", "three");
        Espresso.onView(withId(android.R.id.content)).perform(ViewActions.click());

        Log.d(TAG, "testAsyncTask end");
    }
}

TestingActivity只是一个空活动:

public class TestingActivity extends Activity {

}
 类似资料:
  • 在我的Android应用程序中--登录后,有一个静态同步任务可能会运行几分钟,并将数据拉入手机数据库。 正常情况下,用户可以在同步数据的同时继续使用该应用程序。但是espresso由于某种原因,它正在等待同步AsyncTask完全完成,然后才进入下一个屏幕,我如何告诉espresso继续而不等待? 谢谢

  • 问题内容: 我通过将操作拆分为可用的确切内核数来并行化操作,然后通过启动相同数量的AsyncTask,对数据的不同部分执行相同的操作。 我正在使用以并行化它们的执行。 我想知道每个线程何时完成其工作,以便结合所有结果并执行进一步的操作。 我能怎么做? 问题答案: 您还可以简单地将共享库中的计数器递减作为的一部分。由于在同一线程(主线程)上运行,因此您不必担心同步。 更新1 共享对象可能看起来像这样

  • Espresso的广告特性是,它总是等待Android的UI线程空闲,这样你就不必考虑任何时间问题。但我似乎发现了一个例外:-/ Espresso希望写入一个,其ID是可见的。由于swipe操作尚未完成,第一个片段和第二个片段中的都可见,因此匹配的失败,只有2个匹配项。 如果通过在swipe操作之后添加,手动强制中断,则一切正常。 有人知道怎么做浓缩咖啡等到刷动作完成吗?或者至少有人知道为什么会这

  • 问题内容: 我的一个活动中的一个按钮调用AsyncTask,该AsyncTask更新ListView的SimpleCursorAdapter的基础Cursor。每次单击按钮时,都会为AsyncTask添加一个新线程并完成任务(进入“等待”状态)。如果我单击按钮5次或更多次,则5个AsyncTasks最终以“等待”状态坐在那里。这是正常现象还是在某处内存泄漏? AsyncTask 还有我的onCre

  • 我通读了Dart/flatter中的Async/Await/then,试图理解为什么aysnc函数中的Await不会等到完成后再继续。在我的UI中,有一个按钮调用一个异步方法来返回一个位置,该位置总是返回null,并且不等待函数完成。 该函数将调用推送到一个新的UI页面,该页面选择一个位置,并应返回一个结果。如何使该函数等待结果?我不是在使用异步吗?

  • 问题内容: 我目前正在等待所有承诺按顺序完成,如下所示: 但是,通过这种方式,配置文件和令牌将顺序执行。由于两者彼此独立,因此我希望两者一起独立执行。我认为可以使用Promise.all完成此操作,但是我不确定语法,也找不到任何帮助。 所以我的问题是如何转换上面的api调用以一起运行,然后返回最终输出。 问题答案: