Android自动化追本溯源系列(2): 在控件上执行操作

上回说到,在Android自动化测试时,通过反射机制,我们能获得页面的所有控件。来看一个简单的应用例子:

        ArrayList<View> views = getAllViews();
        for(View view : views)
        {
            Log.d("Views On Activity:", view.getClass().getName());
        }

这样在LogCat里我们就可以打印出所有的View了:

03-27 22:24:52.369: D/Views On Activity:(2123): android.widget.LinearLayout
03-27 22:24:52.369: D/Views On Activity:(2123): com.android.internal.widget.ActionBarContainer
03-27 22:24:52.369: D/Views On Activity:(2123): com.android.internal.widget.ActionBarView
03-27 22:24:52.369: D/Views On Activity:(2123): android.widget.LinearLayout
03-27 22:24:52.369: D/Views On Activity:(2123): android.widget.ImageView
03-27 22:24:52.369: D/Views On Activity:(2123): android.widget.LinearLayout
03-27 22:24:52.369: D/Views On Activity:(2123): android.widget.TextView
03-27 22:24:52.369: D/Views On Activity:(2123): android.widget.TextView
03-27 22:24:52.369: D/Views On Activity:(2123): com.android.internal.widget.ActionBarView$HomeView
03-27 22:24:52.369: D/Views On Activity:(2123): android.widget.ImageView
03-27 22:24:52.369: D/Views On Activity:(2123): android.widget.ImageView
03-27 22:24:52.369: D/Views On Activity:(2123): com.android.internal.view.menu.ActionMenuView
03-27 22:24:52.369: D/Views On Activity:(2123): com.android.internal.widget.ActionBarContextView
03-27 22:24:52.369: D/Views On Activity:(2123): android.widget.FrameLayout
03-27 22:24:52.369: D/Views On Activity:(2123): android.widget.RelativeLayout
03-27 22:24:52.369: D/Views On Activity:(2123): android.widget.RelativeLayout
03-27 22:24:52.369: D/Views On Activity:(2123): android.widget.TextView
03-27 22:24:52.369: D/Views On Activity:(2123): android.widget.TextView
03-27 22:24:52.369: D/Views On Activity:(2123): android.widget.ImageView
03-27 22:24:52.369: D/Views On Activity:(2123): android.widget.ImageView
03-27 22:24:52.369: D/Views On Activity:(2123): android.widget.RelativeLayout
03-27 22:24:52.369: D/Views On Activity:(2123): android.widget.TextView
03-27 22:24:52.369: D/Views On Activity:(2123): android.widget.TextView
03-27 22:24:52.369: D/Views On Activity:(2123): android.widget.TextView
03-27 22:24:52.369: D/Views On Activity:(2123): android.widget.TextView
03-27 22:24:52.369: D/Views On Activity:(2123): android.widget.TextView
03-27 22:24:52.369: D/Views On Activity:(2123): android.widget.Button
03-27 22:24:52.369: D/Views On Activity:(2123): com.android.internal.policy.impl.PhoneWindow$DecorView

我们看到这里罗列了所有的控件,有Layout, TextView, Button 等等。而获得了这些控件,对我们有什么用呢?

Yes,有了这些控件,我们就可以执行相应的操作了!

 比如:

  1. 有了Button,我们可以执行Click On Button操作
  2. 有了TextView,我们就可以得到页面的所有Text,去验证Message或者做Localization Testing
  3. 同样有了ImageView,我们可以执行Click操作,甚至可以得到页面显示的图片
  4. ......

 下面分享一些我们项目中用到的关于这些操作的典型片断:

  • Click 操作
        public void clickOnView(int id)
        {
            View view = solo.getView(id);
            if(view != null)
            {
                solo.clickOnView(view);
            }
        }

 

  • 等待操作
        public boolean isViewGone(int id, long timeout)
        {
            final long endtime = SystemClock.uptimeMillis() + timeout;
            
            while(SystemClock.uptimeMillis() < endtime)
            {
                if(solo.getView(id).hasFocusable())
                {
                    solo.sleep(10);
                }
                else
                {
                    return true;
                }
            }
            
            return false;
        }
  • 获取页面图片
        public Bitmap getSourceIcon()
        {
            BitmapDrawable drawable = (BitmapDrawable) sourceImageView.getDrawable();
            return  drawable.getBitmap();
        }

    这里的sourceImageView变量,就是一个ImageView的实例。

 为了方便,我们在项目中使用了Robotium框架,但是如果追本溯源的话,我们不禁要问:

这些操作是如何实现的?我们自己能不能写?

我们知道Robotium框架是基于Instrumentation,并且市面上大多数的Android测试框架都是基于Instrumentation的,而Instrumentation就是我们做自动化的基石,一层层的跟进Robotium的Click方法,我们会看到最终它是调用Instrumentation的:

public void sendPointerSync (MotionEvent event)

来实现Click操作。

For Example:  Solo.clickOnView(View view) 会调用 clicker.clickOnScreen(view) 跟进去我们会看到下面的代码:

    public void clickOnScreen(float x, float y) {
        long downTime = SystemClock.uptimeMillis();
        long eventTime = SystemClock.uptimeMillis();
        MotionEvent event = MotionEvent.obtain(downTime, eventTime,
                MotionEvent.ACTION_DOWN, x, y, 0);
        MotionEvent event2 = MotionEvent.obtain(downTime, eventTime,
                MotionEvent.ACTION_UP, x, y, 0);
        try{
            inst.sendPointerSync(event);
            inst.sendPointerSync(event2);
            sleeper.sleep(MINISLEEP);
        }catch(SecurityException e){
            Assert.assertTrue("Click can not be completed!", false);
        }
    }

这样我们就明白了,原来在Android automation testing, Click的操作是这么实现的!

总结

要是我们自己来写Android自动化测试框架,我们也可以提供这样一个方法嘛~

 

posted @ 2013-03-28 18:02  大卡尔  阅读(1186)  评论(0编辑  收藏