TouchUtils和ActivityInstrumentationTestCase2用户事件单元测试用例不起作用

时间:2012-03-30 23:11:59

标签: android testing junit android-ndk touch

目前我正在与单元测试框架进行一些努力......

我想做什么

  • 我需要在屏幕上(100,100)和(400,400)以较小的持续时间差异模拟2次点击。
  • 我需要在屏幕上模拟longPressClick让我们说(200,200)
  • 用户单击本机代码并运行Bitmap上的像素操作。
  • 此测试将针对多个成对点集运行,用于分析系统的运行时性能

这是我被困的地方

  • 我正在使用activityInstrumentationTestCase2和touchUtils进行用户点击事件。
  • TouchUtils.longClickView(InstrumentationTestCase测试,View v)工作正常;我能够正确地检测到长按事件,但测试用例甚至在我的UI线程中完成计算/渲染之前就完成了;在这种情况下如何阻止测试退出?
  • 如何在屏幕上模拟2/3用户点击@特定位置?因为TouchUtils.clickView(InstrumentationTestCase测试,View v)只会模拟屏幕中心的用户点击...如何正确地进行操作?

这些是我尝试过的东西,似乎我错过了一些东西:

  • TouchUtils.longClickView(InstrumentationTestCase测试,View v)工作正常...用于创建longClickView ..甚至我能够通过在ACTION_DOWN和ACTION_UP事件之间引入时间延迟来在特定的屏幕位置创建longClickView()..请参考附上的代码
  • 我能够在特定的屏幕位置实现用户点击事件,但是我遇到了一个奇怪的问题..当我从测试用例中取代MotionEvent(100,100)时...框架总是会添加“-76”在Y事件中..不确定为什么会出现这种偏差...我通过在我的输入数据(100,176)中添加76来解决这个问题。有没有人面临类似的问题?
  • 即使看起来这种方法时机非常关键..因为如果我在ACTION_DOWN和ACTION_UP之间放置更多延迟,则事件被检测为longClickPress ...如果我放少一点......“第二次”单击事件(ACTION_DOWN + ACTION_UP)被检测为DoubleTapEvent ..

对于单个用户点击事件模拟,ACTION_UP和ACTION_DOWN ..的正确时序组合应该是什么.. ????????

    @Test
    public void testClick(){
    List<Points> pointSequence = new ArrayList<Points>();
    Log.d(TAG, "FirClick Start Timing : " + SystemClock.uptimeMillis());

    pointSequence.add(new Points(100f,176f));
    pointSequence.add(new Points(100f,176f));       
    singleClickSimulation(pointSequence,false);
    }       

    private void singleClickSimulation(List<Points> pointSequence, Boolean addDelay) {

    long downTime = SystemClock.uptimeMillis();
    long eventTime = SystemClock.uptimeMillis();
    // NOTE : If I do not place this then the event is detected as doubleTap.
    eventTime += 100;
    Instrumentation inst = getInstrumentation();

    MotionEvent event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_DOWN, pointSequence.get(0).getX(), pointSequence.get(0).getY(), 0);
    inst.sendPointerSync(event);                
    //eventTime = SystemClock.uptimeMillis();
    pointSequence.remove(0);        

    //This delay I have added just to test; whether there is enough time for pixel manipulation or not, actually it would be used only at the end of the run of all the test cases for single user click
    if(addDelay){
    eventTime = SystemClock.uptimeMillis() + 3000;
    }
    eventTime += 25;
    event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_UP, pointSequence.get(0).getX(), pointSequence.get(0).getY(), 0);
    inst.sendPointerSync(event);
    pointSequence.remove(0);
}

2 个答案:

答案 0 :(得分:0)

部分答案:

在创建用户点击事件时仍然可以找到造成76px偏差的原因。

我已经能够以50ms的差异模拟单个用户点击事件。 而且我必须以至少300毫秒的速度进行2次点击;这样“SingleTapConfirmed”可以为GeastureDetector类自行触发..

private void singleClickSimulation(List<Points> pointSequence,boolean addDelay) {

    long downTime = SystemClock.uptimeMillis();
    // event time MUST be retrieved only by this way!
    long eventTime = SystemClock.uptimeMillis();

            // This additional time was added between 2 successive clicks 
            // to make sure that "singleTapConfirmed" event can get fired for "GeastureDetector" class.
    eventTime +=400;
    downTime +=400;
    Instrumentation inst = getInstrumentation();

    MotionEvent event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_DOWN, pointSequence.get(0).getX(), pointSequence.get(0).getY(), 0);
    inst.sendPointerSync(event);                
    //eventTime = SystemClock.uptimeMillis();
    pointSequence.remove(0);        


            //50 ms timedelay between ACTION_DOWN and ACTION_UP works well      
    eventTime += 50;
    event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_UP, pointSequence.get(0).getX(), pointSequence.get(0).getY(), 0);
    inst.sendPointerSync(event);
    pointSequence.remove(0);
}

答案 1 :(得分:0)

而不是使用TouchUtils,我用过。

public class TestTouchUtils extends   ActivityInstrumentationTestCase2<TheActivity> {

    public void testTouchUtils() throws Throwable {

        final View button = getActivity().findViewById(R.id.button)

        getActivity().runOnUiThread( new Runnable() {
             public void run() {
                button.performClick();
             }
        });
    }
}

它不会更新仪器/设备上的UI,但会更新仪器内的变量。在我的例子中,按钮更新片段的适配器。 如果我只使用,      TouchUtils.clickView(这个,按钮) 设备上的UI已更新,但变量未更新。

所以我也和TouchUtils结合了。我不知道为什么,但它有效。