为登录Facebook的Android应用程序编写测试:UIAutomator无法在Facebook的用户名字段中填写文本

时间:2016-02-12 02:56:03

标签: android facebook facebook-android-sdk uiautomator android-uiautomator

从这个问题/答案中我得到了使用UIAutomator测试我的应用程序需要登录Facebook的想法。

Writing tests for an Android app that logs into Facebook

我试过

        UiObject2 editText = mDevice.findObject(By.clazz("android.widget.EditText"));
        editText.setText("test@email.com");

和其他事情一样,但无论我做什么,我都无法填写这个领域。我使用hierachyviewer工具看到它是一个EditText。这是一个webview,所以我不知道。

这可能吗?

我的完整测试代码类如下:

package com.greenrobot.yesorno.test;

import android.os.SystemClock;
import android.support.test.InstrumentationRegistry;
import android.support.test.espresso.NoMatchingViewException;
import android.support.test.espresso.UiController;
import android.support.test.espresso.ViewAction;
import android.support.test.rule.ActivityTestRule;
import android.support.test.runner.AndroidJUnit4;
import android.support.test.uiautomator.By;
import android.support.test.uiautomator.UiDevice;
import android.support.test.uiautomator.UiObject2;
import android.test.suitebuilder.annotation.LargeTest;
import android.view.View;

import com.greenrobot.yesorno.Home;
import com.greenrobot.yesorno.R;
import com.jeremyfeinstein.slidingmenu.lib.SlidingMenu;

import org.hamcrest.Matcher;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;

import timber.log.Timber;

import static android.support.test.espresso.Espresso.onData;
import static android.support.test.espresso.Espresso.onView;
import static android.support.test.espresso.action.ViewActions.click;
import static android.support.test.espresso.assertion.ViewAssertions.matches;
import static android.support.test.espresso.matcher.ViewMatchers.isAssignableFrom;
import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
import static android.support.test.espresso.matcher.ViewMatchers.withId;
import static org.hamcrest.Matchers.hasToString;
import static org.hamcrest.Matchers.startsWith;


/**
 * Created by andytriboletti on 1/15/16.
 */
@RunWith(AndroidJUnit4.class)
@LargeTest
public class TestLogin  {

    private UiDevice mDevice;

    private static final String PACKAGE_NAME = "com.greenrobot.yesorno";
    private static final int LAUNCH_TIMEOUT = 5000;

    @Rule
    public ActivityTestRule<Home> mActivityRule = new ActivityTestRule(Home.class);

    public TestLogin() {
        super();
    }

    @Before
    public void initTest() {
        // Initialize UiDevice instance
    
        mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());

//
//        // Start from the home screen
//        mDevice.pressHome();
//
//        // Wait for launcher
    
//        String launcherPackage = mDevice.getCurrentPackageName();
//        mDevice.wait(Until.hasObject(By.pkg(launcherPackage).depth(0)), LAUNCH_TIMEOUT);
//
//        // Launch the app
    
//        Context context = InstrumentationRegistry.getContext();
//        Intent intent = context.getPackageManager().getLaunchIntentForPackage(PACKAGE_NAME);
//
//        // Clear out any previous instances
    
//        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
//        context.startActivity(intent);
//
//        // Wait for the app to appear
    
//        mDevice.wait(Until.hasObject(By.pkg(PACKAGE_NAME).depth(0)), LAUNCH_TIMEOUT);
    }

    public void fillInEmail() {
        onView(withId(R.id.authButton)).perform(click());


            //new UiObject(new UiSelector().description("Email or Phone")).setText("test@email.com");
            //new UiObject(new UiSelector().
           // boolean result = new UiObject(new UiSelector().className(android.widget.EditText.class.getName())).setText("test@email.com");
            //Timber.d(result.getText());
            //UiObject2 editText = new UiObject2(new UiSelector(). className("android.widget.EditText").instance(0));
            //UiObject editText = new UiObject(new UiSelector().text("Email or Phone"));
            UiObject2 editText = mDevice.findObject(By.clazz("android.widget.EditText"));
            editText.setText("test@email.com");
            SystemClock.sleep(5000);


    }
    @Test
    public void testLogin() {
        try {
            onView(withId(R.id.welcome)).check(matches(isDisplayed()));
            Timber.d("Logged out");
            //fillInEmail();
        }
        catch(NoMatchingViewException e) {

            onView(withId(R.id.name_age)).check(matches(isDisplayed()));
            Timber.d("Not logged out");
            onView(withId(R.id.slidingmenumain)).perform(actionOpenDrawer());
            //SystemClock.sleep(5000);
            onData(hasToString(startsWith("Logout")))
                    .inAdapterView(withId(android.R.id.list))
                    .perform(click());

            //fillInEmail();

            //openDrawer(R.id.drawer_layout);
            //Espresso.onView(Matchers.allOf(ViewMatchers.withId(R.id.drawerItemNameTextView), ViewMatchers.hasSibling(ViewMatchers.withText(((NavDrawerItem)item).getItemName())))).perform(ViewActions.click());


        }

//        onView(withText("Hello world!")).check(matches(isDisplayed()));

        //onView(withId(R.id.changeTextBt)).perform(click());

    }


    private static ViewAction actionOpenDrawer() {
        return new ViewAction() {
            @Override
            public Matcher<View> getConstraints() {
                return isAssignableFrom(SlidingMenu.class);
            }

            @Override
            public String getDescription() {
                return "open drawer";
            }

            @Override
            public void perform(UiController uiController, View view) {
                ((SlidingMenu) view).showMenu();
            }
        };
    }
    private static ViewAction actionCloseDrawer() {
        return new ViewAction() {
            @Override
            public Matcher<View> getConstraints() {
                return isAssignableFrom(SlidingMenu.class);
            }

            @Override
            public String getDescription() {
                return "close drawer";
            }

            @Override
            public void perform(UiController uiController, View view) {
                //((SlidingMenu) view).close(GravityCompat.START);
            }
        };
    }
}

编辑:我实际上使用的是uiautomatorviewer而不是hierachyviewer。这是一个屏幕截图,显示它是一个编辑文本。至少根据这个工具。 uiautomator tool view of Facebook login webview

1 个答案:

答案 0 :(得分:2)

我没有在Facebook登录页面上尝试此操作,但我能够在我创建的其他页面上执行此操作。

我能够使用UIObject和UIObject2使用EditText类在Web表单中定位输入框。我能够使用setText()在输入框中设置文本,但是我无法用getText()读出它。

选择HTML输入表单需要一些注意。您可以可靠地选择特定输入的唯一方法是使用instance()来查找第n个索引字段。这意味着您可能应该将搜索范围限制为WebView父对象(否则屏幕上的其他一些EditText可能会抵消所有内容)。

您需要注意的另一件事是WebView的加载时间。它不会立即发生,因此您需要等待一段合理的时间才能让页面加载。

下面是一些示例代码,让我在HTML页面上找到第二个输入框并将文本放入其中:

UiObject input = mDevice.findObject(new UiSelector()
    .instance(1)
    .className(EditText.class));
input.setText("text");