Question

Comment puis-je ouvrir l’onglet dans le test Espresso ?j'ai essayé de faire Espresso.onView(ViewMatchers.withId(R.id.practice_results_tab)).perform(ViewActions.click());, mais ça ne marche pas.Dans ce code, j'ai ouvert la mise en page de cet onglet.Il y a le fichier XML :

    <TabHost
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/practice_tabHost">

        <LinearLayout
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:orientation="vertical">

            <TabWidget
                android:id="@android:id/tabs"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content">
            </TabWidget>

            <FrameLayout
                android:id="@android:id/tabcontent"
                android:layout_width="fill_parent"
                android:layout_height="fill_parent">

                <LinearLayout
                    android:id="@+id/practice_settings_tab"
                    android:layout_width="fill_parent"
                    android:layout_height="fill_parent"
                    android:orientation="vertical">

                </LinearLayout>

                <LinearLayout
                    android:id="@+id/practice_results_tab"
                    android:layout_width="fill_parent"
                    android:layout_height="fill_parent"
                    android:orientation="vertical">

                </LinearLayout>
            </FrameLayout>
        </LinearLayout>
    </TabHost>

Quel identifiant dois-je utiliser pour ouvrir l'onglet ?

Erreur dans logcat :

Caused by: java.lang.RuntimeException: Action will not be performed because the target     view does not match one or more of the following constraints:
at least 90 percent of the view's area is displayed to the user.
Target view: "LinearLayout{id=2131296384, res-name=practice_results_tab, visibility=GONE, width=0, height=0, has-focus=false, has-focusable=false, has-window-focus=true, is-clickable=false, is-enabled=true, is-focused=false, is-focusable=false, is-layout-requested=true, is-selected=false, root-is-layout-requested=false, has-input-connection=false, x=0.0, y=0.0, child-count=1}"
Était-ce utile?

La solution

Code terminé

Vous devez vraiment ajouter du code pour que nous puissions donner une réponse appropriée.Je suppose ici que vous avez utilisé un TabHost et un TabWidget de la même manière que cet exemple : https://maxalley.wordpress.com/2012/10/25/android-creating-a-tab-layout-with-tabhost-and-tabwidget/

J'ai créé un exemple de projet sur https://github.com/hanscappelle/SO-25016397

Votre activité pourrait alors ressembler à ceci :

public class MainActivity extends TabActivity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        TabHost tabHost = getTabHost();

        // setNewTab(context, tabHost, tag, title, icon, contentID);
        this.setNewTab(this, tabHost, "tab1", R.string.textTabTitle1, R.drawable.ic_tab_settings, R.id.practice_settings_tab);
        this.setNewTab(this, tabHost, "tab2", R.string.textTabTitle2, R.drawable.ic_tab_results, R.id.practice_results_tab);

    }

    private void setNewTab(Context context, TabHost tabHost, String tag, int title, int icon, int contentID ){
        TabSpec tabSpec = tabHost.newTabSpec(tag);
        String titleString = getString(title);
        tabSpec.setIndicator(titleString, context.getResources().getDrawable(android.R.drawable.star_on));
        tabSpec.setContent(contentID);
        tabHost.addTab(tabSpec);
    }
}

J'ai trouvé un autre exemple de code sur https://maxalley.wordpress.com/2012/10/27/android-styling-the-tabs-in-a-tabwidget/ avec une méthode d'assistance qui injecte un ImageView pour les onglets.

private View getTabIndicator(Context context, int title, int icon) {
        View view = LayoutInflater.from(context).inflate(R.layout.tab_layout, null);
        ImageView iv = (ImageView) view.findViewById(R.id.imageView);
        iv.setImageResource(icon);
        TextView tv = (TextView) view.findViewById(R.id.textView);
        tv.setText(title);
        return view;
    }

Maintenant, cela devient intéressant car de cette façon, nous pouvons facilement définir un identifiant ou un tag sur ceux injectés. View objets et utilisez-les dans Espresso.

Une solution:Marquer la vue

Si vous adaptez cet assistant pour accepter une balise pour chaque vue, le code de l'assistant ressemblera à ceci :

private View getTabIndicator(Context context, int title, int icon, int viewId, String viewTag) {
        View view = LayoutInflater.from(context).inflate(R.layout.tab_layout, null);
        ImageView iv = (ImageView) view.findViewById(R.id.image_view);
        iv.setImageResource(icon);
        TextView tv = (TextView) view.findViewById(R.id.text_view);
        tv.setText(title);
        tv.setTag(viewTag);
        return view;
    }

Si vous utilisez uniquement des icônes, vous pouvez également définir l'ID sur ImageView.

Et le code Espresso pour cliquer sur ces onglets :

Espresso.onView(ViewMatchers.withTagValue(Matchers.is((Object)"tab1"))).perform(ViewActions.click());

Solution alternative:utilisation des ID de vue

Si vous optez pour des identifiants, vous devez définir ces identifiants quelque part.Utilisez un simple fichier de ressources Android avec quelques définitions d'ID.

Le fichier de ressources d'ID de vue, nommé /values/ids.xml :

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <item name="tab1" type="id" />
</resources>

L'aide adaptée :

private View getTabIndicator(Context context, int title, int icon, int viewId, String viewTag) {
    View view = LayoutInflater.from(context).inflate(R.layout.tab_layout, null);
    ImageView iv = (ImageView) view.findViewById(R.id.image_view);
    iv.setImageResource(icon);
    TextView tv = (TextView) view.findViewById(R.id.text_view);
    tv.setText(title);
    tv.setId(viewId);
    return view;
}

Si vous utilisez uniquement des icônes, vous pouvez également définir l'ID sur ImageView.

Et le code Espresso pour cliquer sur ces onglets :

Espresso.onView(ViewMatchers.withId(R.id.tab1)).perform(ViewActions.click());

À propos des TabHosts en général

Pourquoi avez-vous utilisé ce TabHost en premier lieu ?Notez que cette classe est désormais obsolète.UN ViewPager avec onglets ou la barre d'action pourrait être de meilleures options en fonction de votre cas d’utilisation.

Utiliser l'outil ViewHierarchy

Dans de tels cas, le premier problème est souvent de trouver la bonne vue.Pour cela, utilisez le Afficher la hiérarchie outil.Il fait partie du SDK Android et se trouve dans le répertoire tools.

Vous pouvez le démarrer depuis la ligne de commande comme ceci :

cd ANDROID_SDK_LOCATION/tools
hierarchyviewer

Ou utiliser Android Studio menu:Outils > Android > Moniteur d'appareil Android.Ensuite, ouvrez la perspective Vue hiérarchique à partir du menu du moniteur de périphérique :Fenêtre > Ouvrir la perspective > Vue hiérarchique .

Je préfère la première option simplement parce que Device Monitor en fait beaucoup trop pour nos intentions.

Utilisez maintenant la vue Mise en page en combinaison avec la vue Propriétés de la vue pour rechercher l'ID et les balises de la vue souhaitée.

Quelques instructions sur cet outil : http://developer.android.com/tools/debugging/debugging-ui.html

Autres conseils

la seule chose qui fonctionne pour moi c'est :

public void clickOnTab(String tabText) {    
    Matcher<View> matcher = allOf(withText(tabText),
                                  isDescendantOfA(withId(R.id.ll_tab_container)));
    onView(matcher).perform(click());    
}

ll_tab_container est la disposition linéaire de ma disposition d'onglets personnalisée.et si vous aviez un onglet appelé "shopping", vous le transmettriez comme tabText.

onView(withText("L'étiquette de votre onglet")).perform(click())

Il est également possible de définir une balise sur le texte de votre onglet sans utiliser de méthode d'indicateur personnalisé.Pour ce faire, accédez à l'onglet TextView après sa création.

En utilisant le MainActivity à partir de l'exemple de code de hcpl, cela ressemblerait à ceci :

public MainActivity extends TabActivity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        TabHost tabHost = getTabHost();

        // setNewTab(context, tabHost, tag, title, icon, contentID);
        this.setNewTab(this, tabHost, "tab1", R.string.textTabTitle1, R.drawable.ic_tab_settings, R.id.practice_settings_tab);
        this.setNewTab(this, tabHost, "tab2", R.string.textTabTitle2, R.drawable.ic_tab_results, R.id.practice_results_tab);

        // Set custom tag on first tab
        View tabView1 = tabHost.getTabWidget().getChildAt(0);
        TextView tabView1Text = (TextView) signUpTabView.findViewById(android.R.id.title);
        signUpTextTab.setTag("TAG_TAB_ONE");

        // Set custom tag on second tab
        View tabView2 = tabHost.getTabWidget().getChildAt(1);
        TextView tabView1Text = (TextView) signUpTabView.findViewById(android.R.id.title);
        signUpTextTab.setTag("TAG_TAB_TWO");
    }
}

Ensuite, dans votre test Espresso, vous pourrez accéder aux onglets comme ceci :

onView(withTagValue(Matchers.is((Object)"TAG_TAB_TWO"))).perform(click());
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top