为登录Facebook的Android应用程序编写测试:UIAutomator无法填写Facebook用户名字段中的文本 [英] Writing tests for an android app that logs into Facebook: UIAutomator can't fill in text in Facebook's username field

查看:639
本文介绍了为登录Facebook的Android应用程序编写测试:UIAutomator无法填写Facebook用户名字段中的文本的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



解决方案

我没有尝试这个反对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);


From this question/answer I got the idea to use UIAutomator to test my app that requires logging into Facebook.

Writing tests for an Android app that logs into Facebook

I tried

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

As well as other things but whatever I do I can't get it to fill out the field. I used hierachyviewer tool to see that it was an EditText. It's a webview, though, so I don't know.

Is this possible?

My full test code class is attached below:

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);
            }
        };
    }
}

Edit: I actually used uiautomatorviewer not hierachyviewer. Here's a screenshot showing it's an edit text. At least according to this tool.

解决方案

I didn't try this against a Facebook login page, but I was able to do this on a different page I created.

I was able to use both UIObject and UIObject2 to location an input box in a web form using the EditText class. I was able to both to set the text in the input box using setText(), but I was not able to read it out with getText().

Selecting HTML input forms requires some care. The only way you can reliably select a specific input is by using instance() to find the n'th indexed field. This means you should probably be limiting the scope of your searches to the WebView parent object (otherwise some other EditText on the screen might offset everything).

Another thing you need to look out for is the load time of the WebView. It's not going to happen instantaneously, so you will need to wait some reasonable amount of time to let the page load.

Here is a bit of sample code that let me find the second input box on a HTML page and put text into it:

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

这篇关于为登录Facebook的Android应用程序编写测试:UIAutomator无法填写Facebook用户名字段中的文本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆