为什么androidx espresso.check()会导致androidx.test.espresso.IdlingResourceTimeoutException
我有一些使用androidx Espresso的单元测试,每次运行测试时都会出现以下错误为什么androidx espresso.check()会导致androidx.test.espresso.IdlingResourceTimeoutException,android,unit-testing,android-espresso,Android,Unit Testing,Android Espresso,我有一些使用androidx Espresso的单元测试,每次运行测试时都会出现以下错误 androidx.test.espresso.IdlingResourceTimeoutException:等待[WorkTrackerIdlingResource]变为空闲超时 为什么我会超时? 在我的单元测试中,这行代码超时, onView(带id(R.id.map_容器)).check(匹配项(isDisplayed()) 单元测试类: @RunWith(AndroidJUnit4.class) @L
androidx.test.espresso.IdlingResourceTimeoutException:等待[WorkTrackerIdlingResource]变为空闲超时
为什么我会超时?
在我的单元测试中,这行代码超时,
onView(带id(R.id.map_容器)).check(匹配项(isDisplayed())代码>
单元测试类:
@RunWith(AndroidJUnit4.class)
@LargeTest
public class CanvassFragmentTest extends TopLevelNavFragmentTest<CanvassFragment> {
@NonNull
@Override
protected TopLevelNavFragment getTargetTopLevelNavFragment(@NonNull MainActivity activity) {
return activity.mCanvassFragment;
}
@Test
public void mapContainer_isDisplayed() {
onView(withId(R.id.id1_container)).check(matches(isDisplayed()));
}
}
这是我们注册为规则的代码
@Rule
public final RuleChain mRuleChain;
public UiTest(@NonNull Class<T> activityClass) {
mActivityTestRule = new ActivityTestRule<>(activityClass);
mRuleChain = createRuleChain();
}
@NonNull
private RuleChain createRuleChain() {
RuleChain chain = RuleChain.emptyRuleChain()
.around(new InjectionRule())
.around(new WaitForWorkRule());
if (loggedIn()) {
chain = chain.around(new LoggedInRule());
}
return chain.around(mActivityTestRule);
}
@规则
公共最终规则链;
公共UiTest(@NonNull类activityClass){
mActivityTestRule=新的ActivityTestRule(activityClass);
mRuleChain=createRuleChain();
}
@非空
私有规则链createRuleChain(){
RuleChain=RuleChain.emptyRuleChain()
.around(新注入规则())
.around(新的WaitForWorkRule());
if(loggedIn()){
chain=chain.around(新LoggedInRule());
}
返回链(MacTivityTesture);
}
以下是测试总是超时的简要说明:您设置了一个测试规则,在测试开始之前注册一个空闲资源,然后当您的活动开始时,主线程变忙。通常,当主线程变为空闲时,测试将继续,但您的空闲资源现在会阻止它,并且不会调用onTransitionToIdle。所以无论你设定了多少时间,它都会超时
我认为您在这里使用空闲资源可能没有用处或不正确。如果没有它的用例,您可以排除该规则,它应该可以正常工作。看起来您已经在main活动中注册了idlingsource
。您可以发布活动的代码或注册方式,以及调用onTransitionToIdle
的位置吗?@Aaron我已经添加了您请求的代码。下面简要解释一下测试超时的原因:您设置了一个测试规则,在测试开始前注册空闲资源,然后当您的活动开始时,即主线程变忙时。通常,当主线程变为空闲时,测试将继续,但您的空闲资源现在会阻止它,并且不会调用onTransitionToIdle
。我认为您在这里使用空闲资源可能没有用处或不正确。你这样做有什么特别的原因吗?@Aaron老实说,我没有写代码的规则部分,而开发人员6个月前就离开了。我删除了该规则,编译并运行了测试。我想当我们搬到安卓时,一些根本性的改变。非常感谢你的帮助!如果你想把你的评论变成一个简短的回答,我很乐意接受。
public class WaitForWorkRule implements TestRule {
@Override
public Statement apply(Statement base, Description description) {
return new Statement() {
@Override
public void evaluate() throws Throwable {
WorkTrackerIdlingResource idler = new WorkTrackerIdlingResource();
//Espresso.registerIdlingResources(idler);
IdlingRegistry.getInstance().register(idler);
try {
base.evaluate();
} finally {
IdlingRegistry.getInstance().unregister(idler);
}
}
};
}
/**
* @hide visible for injection
*/
public static class WorkTrackerIdlingResource implements IdlingResource {
private static final String TAG = WorkTrackerIdlingResource.class.getSimpleName();
@Inject
WorkTracker mWorkTracker;
@Nullable
ResourceCallback mResourceCallback;
public WorkTrackerIdlingResource() {
getUiTestInjector().inject(this);
}
@Override
public String getName() {
return TAG;
}
@Override
public boolean isIdleNow() {
boolean idle = !mWorkTracker.isAnyoneWorking();
if (idle && mResourceCallback != null) mResourceCallback.onTransitionToIdle();
return idle;
}
@Override
public void registerIdleTransitionCallback(@Nullable ResourceCallback callback) {
mResourceCallback = callback;
}
}
}
@Rule
public final RuleChain mRuleChain;
public UiTest(@NonNull Class<T> activityClass) {
mActivityTestRule = new ActivityTestRule<>(activityClass);
mRuleChain = createRuleChain();
}
@NonNull
private RuleChain createRuleChain() {
RuleChain chain = RuleChain.emptyRuleChain()
.around(new InjectionRule())
.around(new WaitForWorkRule());
if (loggedIn()) {
chain = chain.around(new LoggedInRule());
}
return chain.around(mActivityTestRule);
}