junit 测试 结果 :匹配 器 " is toast " 未 匹配 以下 任何 根 :

z5btuh9x  于 2022-11-11  发布在  其他
关注(0)|答案(1)|浏览(142)

最近我遇到了一个ToastJUnit Testing的问题。
在我的LoginActivity类中,我有一个Button,它调用以下代码:

Toast.makeText(LoginActivity.this, "toast text", Toast.LENGTH_SHORT).show();

这是一个LoginActivityTest

package com.android_pokladna.LoginActivity;

import android.app.Dialog;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

import androidx.test.core.app.ActivityScenario;
import androidx.test.espresso.UiController;
import androidx.test.espresso.ViewAction;
import androidx.test.rule.ActivityTestRule;

import com.android_pokladna.Model.Login.LoginRequest;
import com.android_pokladna.Model.Login.LoginResponse;
import com.android_pokladna.Other.TokenSaver;
import com.android_pokladna.R;
import com.android_pokladna.ShopActivity.ShopActivity;
import com.android_pokladna.api.ApiClientandService.ApiCallback;
import com.android_pokladna.api.ApiClientandService.ApiClient;

import org.hamcrest.Matcher;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;

import java.util.concurrent.TimeUnit;

import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

import static androidx.test.espresso.Espresso.onView;
import static androidx.test.espresso.action.ViewActions.click;
import static androidx.test.espresso.action.ViewActions.typeText;
import static androidx.test.espresso.assertion.ViewAssertions.doesNotExist;
import static androidx.test.espresso.assertion.ViewAssertions.matches;
import static androidx.test.espresso.matcher.RootMatchers.isDialog;
import static androidx.test.espresso.matcher.RootMatchers.isFocusable;
import static androidx.test.espresso.matcher.RootMatchers.isPlatformPopup;
import static androidx.test.espresso.matcher.RootMatchers.withDecorView;
import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
import static androidx.test.espresso.matcher.ViewMatchers.isRoot;
import static androidx.test.espresso.matcher.ViewMatchers.withId;
import static androidx.test.espresso.matcher.ViewMatchers.withText;
import static androidx.test.internal.runner.junit4.statement.UiThreadStatement.runOnUiThread;
import static org.hamcrest.Matchers.endsWith;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;
import static org.junit.Assert.*;

public class LoginActivityTest {

    @Rule
    public ActivityTestRule<LoginActivity> activityTestRule = new ActivityTestRule(LoginActivity.class);
    private LoginActivity loginActivity = null;

    public static ViewAction waitFor(final long millis) {
        return new ViewAction() {
            @Override
            public Matcher<View> getConstraints() {
                return isRoot();
            }

            @Override
            public String getDescription() {
                return "Wait for " + millis + " milliseconds.";
            }

            @Override
            public void perform(UiController uiController, final View view) {
                uiController.loopMainThreadForAtLeast(millis);
            }
        };
    }

    @Before
    public void setUp() throws Exception {
        loginActivity = activityTestRule.getActivity();

        //clears all system dialogs
        loginActivity.sendBroadcast(new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS));
    }

    @Test
    public void testDialogButtonClick() throws Throwable {
        onView(withId(R.id.activityLoginButtonEnter)).perform(click());
        onView(withId(R.id.activityLoginDialogButton)).perform(click());
        onView(withText("TEXT")).inRoot(new ToastMatcher())
                .check(matches(withText("TEXT")));
    }

    @After
    public void tearDown() throws Exception {
        loginActivity = null;
    }
}

问题在于这部分代码:

onView(withText("toast text")).inRoot(new ToastMatcher())
                .check(matches(withText("toast text")));

会引发error

androidx.test.espresso.NoMatchingRootException: Matcher 'is toast' did not match any of the following roots: [Root{application-window-token=android.view.ViewRootImpl$W@a78c87f, window-token=android.view.ViewRootImpl$W@a78c87f, has-window-focus=true, layout-params-type=2, layout-params-string={(0,0)(wrapxwrap) gr=CENTER sim={adjust=pan} ty=APPLICATION fmt=TRANSPARENT wanim=0x10302ff
  fl=DIM_BEHIND SPLIT_TOUCH HARDWARE_ACCELERATED
  fitTypes=STATUS_BARS NAVIGATION_BARS CAPTION_BAR}, decor-view-string=DecorView{id=-1, visibility=VISIBLE, width=1144, height=1300, has-focus=false, has-focusable=true, has-window-focus=true, is-clickable=false, is-enabled=true, is-focused=false, is-focusable=false, is-layout-requested=false, is-selected=false, layout-params={(0,0)(wrapxwrap) gr=CENTER sim={adjust=pan} ty=APPLICATION fmt=TRANSPARENT wanim=0x10302ff
  fl=DIM_BEHIND SPLIT_TOUCH HARDWARE_ACCELERATED
  fitTypes=STATUS_BARS NAVIGATION_BARS CAPTION_BAR}, tag=null, root-is-layout-requested=false, has-input-connection=false, x=0.0, y=0.0, child-count=1}}, Root{application-window-token=android.view.ViewRootImpl$W@3be404c, window-token=android.view.ViewRootImpl$W@3be404c, has-window-focus=false, layout-params-type=1, layout-params-string={(0,0)(fillxfill) sim={adjust=pan} ty=BASE_APPLICATION wanim=0x10302fe
  fl=LAYOUT_IN_SCREEN LAYOUT_INSET_DECOR SPLIT_TOUCH HARDWARE_ACCELERATED DRAWS_SYSTEM_BAR_BACKGROUNDS
  pfl=FORCE_DRAW_STATUS_BAR_BACKGROUND FIT_INSETS_CONTROLLED
  fitSides=}, decor-view-string=DecorView{id=-1, visibility=VISIBLE, width=2560, height=1600, has-focus=false, has-focusable=true, has-window-focus=false, is-clickable=false, is-enabled=true, is-focused=false, is-focusable=false, is-layout-requested=false, is-selected=false, layout-params={(0,0)(fillxfill) sim={adjust=pan} ty=BASE_APPLICATION wanim=0x10302fe
  fl=LAYOUT_IN_SCREEN LAYOUT_INSET_DECOR SPLIT_TOUCH HARDWARE_ACCELERATED DRAWS_SYSTEM_BAR_BACKGROUNDS
  pfl=FORCE_DRAW_STATUS_BAR_BACKGROUND FIT_INSETS_CONTROLLED
  fitSides=}, tag=null, root-is-layout-requested=false, has-input-connection=false, x=0.0, y=0.0, child-count=3}}]
    at dalvik.system.VMStack.getThreadStackTrace(Native Method)
    at java.lang.Thread.getStackTrace(Thread.java:1736)
    at androidx.test.espresso.base.DefaultFailureHandler.getUserFriendlyError(DefaultFailureHandler.java:12)
    at androidx.test.espresso.base.DefaultFailureHandler.handle(DefaultFailureHandler.java:7)
    at androidx.test.espresso.ViewInteraction.waitForAndHandleInteractionResults(ViewInteraction.java:8)
    at androidx.test.espresso.ViewInteraction.check(ViewInteraction.java:12)
    at com.android_pokladna.LoginActivity.LoginActivityTest.testDialogButtonClick(LoginActivityTest.java:116)

Tests ran to completion.

test类中,我使用了如下所示的ToastMatcher类:

package com.android_pokladna.LoginActivity;

import android.os.IBinder;

import android.view.WindowManager;

import androidx.test.espresso.Root;

import org.hamcrest.Description;
import org.hamcrest.TypeSafeMatcher;

public class ToastMatcher extends TypeSafeMatcher<Root> {
    /*
       Author: http://www.qaautomated.com/2016/01/how-to-test-toast-message-using-espresso.html
    */

    @Override    public void describeTo(Description description) {
        description.appendText("is toast");
    }

    @Override    public boolean matchesSafely(Root root) {
        int type = root.getWindowLayoutParams().get().type;
        if ((type == WindowManager.LayoutParams.TYPE_TOAST)) {
            IBinder windowToken = root.getDecorView().getWindowToken();
            IBinder appToken = root.getDecorView().getApplicationWindowToken();
            if (windowToken == appToken) {
                return true;
            }
        }
        return false;
    }
}

我已经看到很多人都有类似的问题。我是根据一个测试成功的视频来做的:https://www.youtube.com/watch?v=L037q8MGkGA&ab_channel=CodingWithMitch他的视频真的很有帮助,但我不明白我得到的错误。测试需要一段时间才能完成,当toast得到测试。它已经走了,也许这就是为什么它抛出一个错误。
如果有人能帮助我,我将不胜感激。谢谢你的帮助!

dwthyt8l

dwthyt8l1#

这里我也遇到了与inRoot相关的相同错误,因此我使用了另一个解决方案来Assert吐司消息,用UIAutomator和assertTrue替换了inRootToastMatcher类:

import androidx.test.platform.app.InstrumentationRegistry
import junit.framework.Assert.assertTrue
import androidx.test.uiautomator.By
import androidx.test.uiautomator.UiDevice

val device: UiDevice
        get() = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())

assertTrue(device.hasObject(By.text(toastMessageDuplicated)))

相关问题