简体   繁体   English

Espresso 测试在解组时导致“ClassNotFoundException”(在基本应用程序上重现)

[英]Espresso tests cause "ClassNotFoundException when unmarshalling" (REPRODUCED on basic app)

It seems that this unmarshalling exception always gets thrown when an activity is recreated with saved instance state during espresso tests.在 espresso 测试期间使用保存的实例状态重新创建活动时,似乎总是会抛出此解组异常。 I have reproduced it with a very basic android app.我用一个非常基本的 android 应用程序复制了它。 Here are the steps:以下是步骤:

  1. Create an android app with two activities which each have one button.创建一个带有两个活动的 Android 应用程序,每个活动都有一个按钮。 The button on the first activity opens the second activity.第一个活动上的按钮打开第二个活动。 The button on the second activity closes the current activity.第二个活动上的按钮关闭当前活动。

  2. Add an espresso test which simply opens the first activity, clicks the button (to open the second activity), then clicks the button on the second activity (to finish the second activity and go back to the first activity).添加一个 espresso 测试,它只需打开第一个活动,单击按钮(打开第二个活动),然后单击第二个活动上的按钮(完成第二个活动并返回到第一个活动)。

  3. On your emulator, be sure to enable "Don't Keep Activities" on your emulator.在您的模拟器上,确保在您的模拟器上启用“不要保持活动”。

In my real app, it varies based on the activity which class will be "unknown" to cause the unmarshalling.在我的真实应用程序中,它根据活动而变化,哪个类将是“未知的”以导致解组。 In this specific example, it's apparently the toolbar.在这个特定示例中,它显然是工具栏。 I have found that by removing specific entries ("androidx.lifecycle.BundlableSavedStateRegistry.key" and "android:viewHierarchyState") from the saved instance state that it will workaround this exception during espresso tests, but of course then things don't get restored correctly.我发现通过从保存的实例状态中删除特定条目(“androidx.lifecycle.BundlableSavedStateRegistry.key”和“android:viewHierarchyState”),它将在浓缩咖啡测试期间解决此异常,但当然事情不会恢复正确。 And I'll reiterate that this is only a problem while running espresso tests.我会重申,这只是运行 espresso 测试时的问题。 When performing the same exact test steps manually, everything unmarshalls correctly and there are no exceptions.手动执行相同的精确测试步骤时,一切都会正确解组,并且没有例外。

Changing sdk versions doesn't seem to help either.更改 sdk 版本似乎也无济于事。

That's it.就是这样。

Here's all the gory code:这是所有的血腥代码:

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
//        // This will cause the exception to not be thrown during espresso tests
//        if(savedInstanceState != null) {
//            savedInstanceState.remove("androidx.lifecycle.BundlableSavedStateRegistry.key");
//            savedInstanceState.remove("android:viewHierarchyState");
//        }
        

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        findViewById(R.id.open_button).setOnClickListener(v -> startActivity(new Intent(MainActivity.this, ChildActivity.class)));
    }
}
public class ChildActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_child);

        findViewById(R.id.close_button).setOnClickListener(v -> finish());
    }
}
@LargeTest
@RunWith(AndroidJUnit4.class)
public class MainActivityTest {

    @Rule
    public ActivityTestRule<MainActivity> mActivityTestRule = new ActivityTestRule<>(MainActivity.class);

    @Test
    public void test() {
        onView(withId(R.id.open_button)).perform(click());
        onView(withId(R.id.close_button)).perform(click());
        onView(withId(R.id.open_button)).check(matches(isDisplayed()));
    }
}
androidx.test.espresso.PerformException: Error performing 'single click - At Coordinates: 115, 272 and precision: 16, 16' on view 'view.getId() is <2131231192/com.example.myapplication:id/close_button>'.
    at androidx.test.espresso.PerformException$Builder.build(PerformException.java:1)
    at androidx.test.espresso.base.PerformExceptionHandler.handleSafely(PerformExceptionHandler.java:8)
    at androidx.test.espresso.base.PerformExceptionHandler.handleSafely(PerformExceptionHandler.java:9)
    at androidx.test.espresso.base.DefaultFailureHandler$TypedFailureHandler.handle(DefaultFailureHandler.java:4)
    at androidx.test.espresso.base.DefaultFailureHandler.handle(DefaultFailureHandler.java:5)
    at androidx.test.espresso.ViewInteraction.waitForAndHandleInteractionResults(ViewInteraction.java:8)
    at androidx.test.espresso.ViewInteraction.desugaredPerform(ViewInteraction.java:11)
    at androidx.test.espresso.ViewInteraction.perform(ViewInteraction.java:8)
    at com.example.myapplication.MainActivityTest.mainActivityTest(MainActivityTest.java:31)
    ... 32 trimmed
Caused by: android.os.BadParcelableException: ClassNotFoundException when unmarshalling: androidx.appcompat.widget.Toolbar$SavedState
    at android.os.Parcel.readParcelableCreator(Parcel.java:2839)
    at android.os.Parcel.readParcelable(Parcel.java:2765)
    at android.os.Parcel.readValue(Parcel.java:2668)
    at android.os.Parcel.readSparseArrayInternal(Parcel.java:3118)
    at android.os.Parcel.readSparseArray(Parcel.java:2351)
    at android.os.Parcel.readValue(Parcel.java:2725)
    at android.os.Parcel.readArrayMapInternal(Parcel.java:3037)
    at android.os.BaseBundle.initializeFromParcelLocked(BaseBundle.java:288)
    at android.os.BaseBundle.unparcel(BaseBundle.java:232)
    at android.os.Bundle.getSparseParcelableArray(Bundle.java:1010)
    at com.android.internal.policy.PhoneWindow.restoreHierarchyState(PhoneWindow.java:2133)
    at android.app.Activity.onRestoreInstanceState(Activity.java:1135)
    at android.app.Activity.performRestoreInstanceState(Activity.java:1090)
    at android.app.Instrumentation.callActivityOnRestoreInstanceState(Instrumentation.java:1317)
    at android.app.ActivityThread.handleStartActivity(ActivityThread.java:2953)
    at android.app.servertransaction.TransactionExecutor.performLifecycleSequence(TransactionExecutor.java:180)
    at android.app.servertransaction.TransactionExecutor.cycleToPath(TransactionExecutor.java:165)
    at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:142)
    at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:70)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1808)
    at android.os.Handler.dispatchMessage(Handler.java:106)
    at androidx.test.espresso.base.Interrogator.loopAndInterrogate(Interrogator.java:14)
    at androidx.test.espresso.base.UiControllerImpl.loopUntil(UiControllerImpl.java:8)
    at androidx.test.espresso.base.UiControllerImpl.loopUntil(UiControllerImpl.java:1)
    at androidx.test.espresso.base.UiControllerImpl.injectMotionEvent(UiControllerImpl.java:6)
    at androidx.test.espresso.action.MotionEvents.sendUp(MotionEvents.java:7)
    at androidx.test.espresso.action.MotionEvents.sendUp(MotionEvents.java:1)
    at androidx.test.espresso.action.Tap.sendSingleTap(Tap.java:5)
    at androidx.test.espresso.action.Tap.sendSingleTap$bridge(Unknown Source:0)
    at androidx.test.espresso.action.Tap$1.sendTap(Tap.java:3)
    at androidx.test.espresso.action.GeneralClickAction.perform(GeneralClickAction.java:6)
    at androidx.test.espresso.ViewInteraction$SingleExecutionViewAction.perform(ViewInteraction.java:2)
    at androidx.test.espresso.ViewInteraction.doPerform(ViewInteraction.java:25)
    at androidx.test.espresso.ViewInteraction.doPerform$bridge(Unknown Source:0)
    at androidx.test.espresso.ViewInteraction$1.call(ViewInteraction.java:2)
    at androidx.test.espresso.ViewInteraction$1.call(ViewInteraction.java:1)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at android.os.Handler.handleCallback(Handler.java:873)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:193)
    at android.app.ActivityThread.main(ActivityThread.java:6669)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)

据我所知,您应该改为使用ActivityScenario ,然后使用ActivityScenario.moveToStateActivityScenario.recreate测试不同活动的状态。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 ParcelableException:解组时出现ClassNotFoundException - ParcelableException: ClassNotFoundException when unmarshalling 解组 Parcelable 时出现 ClassNotFoundException - ClassNotFoundException when unmarshalling a Parcelable BadParcelableException: ClassNotFoundException 解组时 - BadParcelableException: ClassNotFoundException when unmarshalling BadParcelableException:ClassNotFoundException 解组时:android.support.v4.app.FragmentManagerState - BadParcelableException:ClassNotFoundException when unmarshalling: android.support.v4.app.FragmentManagerState 解组自定义类时ClassNotFoundException - ClassNotFoundException when unmarshalling Custom Class android.os.BadParcelableException:解组时出现ClassNotFoundException: - android.os.BadParcelableException: ClassNotFoundException when unmarshalling: Android Parcelable 问题 - 解组时出现 ClassNotFoundException - Android Parcelable Issue - ClassNotFoundException when Unmarshalling android.os.BadParcelableException:解组时出现 ClassNotFoundException - android.os.BadParcelableException: ClassNotFoundException when unmarshalling BadParcelableException:解组时的ClassNotFoundException:(空类名) - BadParcelableException: ClassNotFoundException when unmarshalling: (empty classname) Android:解组java.lang.ClassNotFoundException时找不到类 - Android : Class not found when unmarshalling java.lang.ClassNotFoundException
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM