从这个问题/答案中我得到了使用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。这是一个屏幕截图,显示它是一个编辑文本。至少根据这个工具。
答案 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");