gpt4 book ai didi

安卓 Espresso : Make assertion while button is kept pressed

转载 作者:塔克拉玛干 更新时间:2023-11-02 22:31:06 26 4
gpt4 key购买 nike

我是 Android 上的 Espresso 的新手,我遇到了以下问题:我希望 Espresso 在按钮上执行长按(或其他操作),当按钮一直被按下时,我想检查不同 View 的状态。

在(或多或少)伪代码中:

onView(withId(button_id)).perform(pressButtonDown());
onView(withId(textBox_id)).check(matches(withText("Button is pressed")));
onView(withId(button_id)).perform(releaseButton());

我尝试使用 MotionEvents.sendDown() 和 .sendUp() 编写 2 个自定义点击,PRESS 和 RELEASE,但没有成功。如果这是正确的路径,我可以发布目前为止得到的代码。

编辑:

public class PressViewActions
{
public static ViewAction pressDown(){
return new GeneralClickAction(HoldTap.DOWN, GeneralLocation.CENTER, Press.THUMB);
}

public static ViewAction release() {
return new GeneralClickAction(HoldTap.UP, GeneralLocation.CENTER, Press.THUMB);
}
}

以及 Tappers 的代码:

public enum HoldTap implements Tapper {

DOWN {
@Override
public Tapper.Status sendTap(UiController uiController, float[] coordinates, float[] precision)
{
checkNotNull(uiController);
checkNotNull(coordinates);
checkNotNull(precision);

DownResultHolder res = MotionEvents.sendDown(uiController, coordinates, precision);

ResultHolder.setController(uiController);
ResultHolder.setResult(res);

return Status.SUCCESS;
}
},

UP{
@Override
public Tapper.Status sendTap(UiController uiController, float[] coordinates, float[] precision)
{
DownResultHolder res = ResultHolder.getResult();
UiController controller = ResultHolder.getController();

try {
if(!MotionEvents.sendUp(controller, res.down))
{
MotionEvents.sendCancel(controller, res.down);
return Status.FAILURE;
}

}
finally {
//res.down.recycle();
}

return Status.SUCCESS;
}
}
}

我得到的错误如下:

android.support.test.espresso.PerformException: Error performing 'up click' on view 'with id: de.test.app:id/key_ptt'.
...
...
Caused by: java.lang.RuntimeException: Couldn't click at: 281.5,1117.5 precision: 25.0, 25.0 . Tapper: UP coordinate provider: CENTER precision describer: THUMB. Tried 3 times. With Rollback? false

希望对您有所帮助。

我们将不胜感激任何帮助和想法!

提前很多坦克!

最佳答案

Android 中的点击由两个事件组成,一个按下事件和一个向上/取消事件。如果您想将这两者分开,则不能进行“点击”,因为它们已经包含了两者。

也就是说,您的想法可行,您只需要使用一个较低级别的 API,即 UiController 以及 MotionEvents 中的辅助方法。不过请注意:由于“释放” View 需要先保留它,如果您不进行适当的清理,您的测试将相互依赖。

示例:在一个测试中,您按下了一个 View ,测试失败了,然后在另一个测试中,您释放了一个您没有点击的 View :您的第二个测试本不应该通过。

我上传于 my github一个完整的样本。这里是要点。先上测试代码:

@Before
public void setUp() throws Exception {
super.setUp();
injectInstrumentation(InstrumentationRegistry.getInstrumentation());
getActivity();
}

@After
public void tearDown() throws Exception {
super.tearDown();
LowLevelActions.tearDown();
}

@Test
public void testAssertWhilePressed() {
onView(withId(R.id.button)).perform(pressAndHold());
onView(withId(R.id.text)).check(matches(withText("Button is held down")));
onView(withId(R.id.button)).perform(release());
}

然后是 LowLevelActions:

public class LowLevelActions {
static MotionEvent sMotionEventDownHeldView = null;

public static PressAndHoldAction pressAndHold() {
return new PressAndHoldAction();
}

public static ReleaseAction release() {
return new ReleaseAction();
}

public static void tearDown() {
sMotionEventDownHeldView = null;
}

static class PressAndHoldAction implements ViewAction {
@Override
public Matcher<View> getConstraints() {
return isDisplayingAtLeast(90); // Like GeneralClickAction
}

@Override
public String getDescription() {
return "Press and hold action";
}

@Override
public void perform(final UiController uiController, final View view) {
if (sMotionEventDownHeldView != null) {
throw new AssertionError("Only one view can be held at a time");
}

float[] precision = Press.FINGER.describePrecision();
float[] coords = GeneralLocation.CENTER.calculateCoordinates(view);
sMotionEventDownHeldView = MotionEvents.sendDown(uiController, coords, precision).down;
// TODO: save view information and make sure release() is on same view
}
}

static class ReleaseAction implements ViewAction {
@Override
public Matcher<View> getConstraints() {
return isDisplayingAtLeast(90); // Like GeneralClickAction
}

@Override
public String getDescription() {
return "Release action";
}

@Override
public void perform(final UiController uiController, final View view) {
if (sMotionEventDownHeldView == null) {
throw new AssertionError("Before calling release(), you must call pressAndHold() on a view");
}

float[] coords = GeneralLocation.CENTER.calculateCoordinates(view);
MotionEvents.sendUp(uiController, sMotionEventDownHeldView, coords);
}
}
}

关于安卓 Espresso : Make assertion while button is kept pressed,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32010927/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com