使用Robotium在自定义ViewGroup中测试拖放行为

时间:2015-03-04 00:36:35

标签: android testing drag-and-drop tdd robotium

我正在尝试在自定义ViewGroup中测试拖放行为。我尝试使用Espresso,但它没有这种功能。所以现在我正在尝试使用Robotium。但我的测试是给出了这个错误:

  

java.lang.RuntimeException:无法从主应用程序线程

调用此方法

代码:

public void testDragAndDrop() throws Exception {
    solo.unlockScreen();

    View v = solo.getView(1);

    int width = v.getWidth();
    int height = v.getHeight();

    final float x_start = v.getX() + width/2;
    final float y_start = v.getY() + height/2;

    final float x_end = x_start + width;
    final float y_end = y_start + height;

    v.setOnLongClickListener(new View.OnLongClickListener() {
        @Override
        public boolean onLongClick(View v) {
            Log.d("onLongClick", "onLongClick!!");
            solo.drag(x_start, x_end, y_start, y_end, 50);
            return true;
        }
    });
    solo.clickLongOnView(v, 5000);
}

编辑:

我查看了TouchUtils并且有两种方法(longClickView和拖动),当它们合并时,似乎完全符合我的要求。所以这是我的两种方法的组合版本:

public void longClickViewAndDrag(InstrumentationTestCase test,
                          View v,
                          float toX, float toY,
                          int stepCount) {
    int[] xy = new int[2];
    v.getLocationOnScreen(xy);

    final int viewWidth = v.getWidth();
    final int viewHeight = v.getHeight();

    float x = xy[0] + (viewWidth / 2.0f);
    float y = xy[1] + (viewHeight / 2.0f);

    Instrumentation inst = test.getInstrumentation();

    long downTime = SystemClock.uptimeMillis();
    long eventTime = SystemClock.uptimeMillis();

    MotionEvent event = MotionEvent.obtain(downTime, eventTime,
                                           MotionEvent.ACTION_DOWN, x, y, 0);
    inst.sendPointerSync(event);
    inst.waitForIdleSync();

    eventTime = SystemClock.uptimeMillis();
    final int touchSlop = ViewConfiguration.get(v.getContext()).getScaledTouchSlop();
    event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_MOVE,
                               x + touchSlop / 2, y + touchSlop / 2, 0);
    inst.sendPointerSync(event);
    inst.waitForIdleSync();

    try {
        Thread.sleep((long)(ViewConfiguration.getLongPressTimeout() * 1.5f));
    } catch (InterruptedException e) {
        e.printStackTrace();
    }

    float yStep = (toY - y) / stepCount;
    float xStep = (toX - x) / stepCount;

    for (int i = 0; i < stepCount; ++i) {
        Log.d("STEP", "..." + i);
        y += yStep;
        x += xStep;
        eventTime = SystemClock.uptimeMillis();
        event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_MOVE, x, y, 0);
        inst.sendPointerSync(event);
    }

    eventTime = SystemClock.uptimeMillis();
    event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_UP, x, y, 0);
    inst.sendPointerSync(event);
    inst.waitForIdleSync();
}

由于某种原因,测试在执行inst.sendPointerSync(event)后停止。

编辑:

我创建了一篇更好地描述真实问题的新帖子:

Using TouchUtils in Android testing

1 个答案:

答案 0 :(得分:0)

Robotiummethod

public void drag(
        float fromX,
        float toX,
        float fromY,
        float toY,
        int stepCount
)