Robotium 测试资料

准备工具:Robotium资料下载

  • 知识准备:

    1. java基础知识,如基本的数据结构、语法结构、类、继承等
    2. 对Android系统较为熟悉,了解四大组件,会编写简单的Android应用程序
    3. 熟悉Eclipse IDE使用方法
    4. 有足够的耐心与探索精神,遇到问题可以熟练的Google
    • 环境搭建

    1. 安装jdk,配置环境变量,如果不会请自行Google
    2. 下载安装Android SDK,并更新
    3. 下载Eclipse,并安装ADT插件,集成Android SDK
    • Robotium新手入门

      1. 下载Robotium官方例子以及最新的JAR
      2. 打开Eclipse导入被测试工程

        导入被测工程

        点击查看大图

      3. 创建测试工程:选择Android Test Project,并点击下一步,然后再测试工程项目中新建测试类

      4. 新建工程后,选择目标工程

      5. 新建测试类

        点击查看大图

        点击查看大图

      6. 输入工程名,并点击下一步

        点击查看大图

        点击查看大图

      7. 选择被测工程NotePad,并点击完成

        4

        点击查看大图

      8. 在测试工程中新建lib文件夹

        5

        点击查看大图

      9. 将下载好的Robotium jar包拷入lib中,并在build path中将jar包引入工程

        7

        点击查看大图

      10. 打开测试工程中的manifest.xml文件,修改如下

        12

        点击查看大图

    1
    
     
      1. 新建junit test case,选择junit4,并输入类名,点击完成

        13

        点击查看大图

      2. 打开新建的测试类,修改继承ActivityInstrumentationTestCase2<NotesList>,创建构造方法,并编写测试代码,具体如图

        14

        点击查看大图

        1. package com.xzw.test;
        2.   import com.jayway.android.robotium.solo.Solo;
        3.   import com.xzw.example.EditorActivity;
        4.   import android.test.ActivityInstrumentationTestCase2;
        5.   public class Test extends ActivityInstrumentationTestCase2<EditorActivity>{
        6.   private Solo solo;
        7.   public Test(){
        8.   super(EditorActivity.class);
        9.   }
        10.   @Override
        11.   protected void setUp() throws Exception {
        12.   //setUp() is run before a test case is started.
        13.   //This is where the solo object is created.
        14.   solo = new Solo(getInstrumentation(), getActivity());
        15.   }
        16.   @Override
        17.   protected void tearDown() throws Exception {
        18.   //tearDown() is run after a test case has finished.
        19.   //finishOpenedActivities() will finish all the activities that have been opened during the test execution.
        20.   solo.finishOpenedActivities();
        21.   }
        22.   /**
        23.   * 测试点击事件
        24.   */
        25.   public void testClick(){
        26.   solo.assertCurrentActivity("进入EditorActivity", "EditorActivity");
        27.   try {
        28.   Thread.sleep(1000);
        29.   //休息1秒
        30.   } catch (InterruptedException e) {
        31.   e.printStackTrace();
        32.   }
        33.   solo.clickOnEditText(0);
        34.   //点击输入框
        35.   try {
        36.   Thread.sleep(1000);
        37.   //休息1秒
        38.   } catch (InterruptedException e) {
        39.   // TODO Auto-generated catch block
        40.   e.printStackTrace();
        41.   }
        42.   solo.enterText(0, "xzw");
        43.   //往第一个EditText,输入文本.第一个为0
        44.   solo.clickOnButton("Click");
        45.   //点击按钮
        46.   solo.takeScreenshot();
        47.   //屏幕截图,并保存到 "/sdcard/Robotium-Screenshots/".
        48.   boolean expected = true;
        49.   boolean actual = solo.searchText("xx");
        50.   //查找含有xx字符的text,如果没有则返回false
        51.   //验证预期结果
        52.   assertEquals("xx is not found", expected, actual);
        53.   } }

         ///测试用例2//

      3. public void testClick2() {
          mSolo.assertCurrentActivity("BookActivity", BookActivity.class);
          try {
           Thread.sleep(1000);
          } catch (Exception e) {
           e.printStackTrace();
          }
          mSolo.clickOnEditText(0);
          try {
           Thread.sleep(1000);
          } catch (Exception e) {
           e.printStackTrace();
          }
          mSolo.enterText(0, "2222222");

      4. //tv_book 是要测试的目标apk的BookActivity中的R.id.tv_book,通过id拿到view控件
          mSolo.clickOnView(mSolo.getView("tv_book"));
          try {
           Thread.sleep(1000);
          } catch (Exception e) {
           e.printStackTrace();
          }

          mSolo.takeScreenshot();
          boolean expected = true;
          boolean actual = mSolo.searchText("备注");
          assertEquals("是否相等", expected, actual);

         }
         
         public void testClick1() {
          mSolo.assertCurrentActivity("BookActivity", BookActivity.class);
          mSolo.clickOnView(mSolo.getView("btn_ordering_get_verify"));
         }

         

         

    1. 编写完成后,打开模拟器或者连接上真机,右击测试类,选择Android junit Test

      15

      点击查看大图

    2. Eclipse会切换到junit界面,此时模拟器(真机)会自动执行测试,通过左边界面可以看到运行结果

      16

      点击查看大图

    3. 一个简单的测试就结束了。如果你没有遇到问题,那么恭喜你继续更深一步学习,如果你遇到问题了,不要急~请先确保你的操作过程没有出任何错误,其次我列出你可能遇到的错误,如果还是没有解决请Google或者联系我们

    1、最常见的:java.lang.NoClassDefFoundError: com.jayway.android.robotium.solo.Solo

    解决方法:如图操作后再clean工程34

  •  

  • adb shell am instrument -e class com.android.test.test.TestCheck#testClick1,com.android.test.test.TestCheck#testClick2 -w com.android.test.test/android.test.InstrumentationTestR
    unner

  • 还可以使用adb 命令执行测试用例,比如连续执行一个测试用例类MarkActivity中的2个测试方法test_hello_world和test_click_btn,使用adb 执行前需要将要测试的目标apk 安装,同时将写好测试用例的apk也要安装到手机上面,方可执行adb命令

  • adb shell am instrument -e class com.android.test.MarkActivity#test_hello_world,com.android.test.MarkActivity#test_click_btn -w com.android.test.MarkActivity/android.test.InstrumentationTestRunner

  • adb shell am instrument -e class 测试用例类(com.android.test.MarkActivity)#测试用例的方法名(test_hello_word),测试用例类(com.android.test.MarkActivity)#测试用例的方法名(test_hello_word),-w com.android.test(类的包名)/android.test.InstrumentationTestRunner(标准的android要这样写)

  •  

    //测试实例2/

    robotium的一个测试尝试

    这几天一直在学习robotium,但是在网上找了很久除了一个测试noteslist的例子外,其他基本上没有多少资料,但是网上关于noteslist的例子在我这不知道为什么老是行不同,于是就觉得自己弄,不按照网上的提供的方法了,经过2天的摸索和研究终于在今天搞定,下面就把我的成果分享给大家:

    1.启动Eclipse执行 New --> Project --> Android Project --> Create Project from existing sample --> NotePad将自带的例子导入进来.

    2.将robotium导入到刚新建的工程中如图

    3、在该工程中新建一个类并将从robotium官网下载的例子粘贴到刚建的类中,如图

    4、在AndroidManifest.xml中添加如下内容:

    <uses-library android:name="android.test.runner" />
        </application>
        <uses-sdk android:minSdkVersion="10" android:targetSdkVersion="10"/>
        <instrumentation android:targetPackage="com.example.android.notepad" //要测试的包
                         android:name="android.test.InstrumentationTestRunner" />

    5、现在就可以运行了,下面是我的测试结果:

    6、为了熟悉这些测试代码自己尝试了修改源代码,修改够的内容如下:

    package com.jayway.test;
    import com.example.android.notepad.NotesList;
    import com.jayway.android.robotium.solo.Solo;
    import android.test.ActivityInstrumentationTestCase2;
    import android.test.suitebuilder.annotation.Smoke;

    public class NotePadtest extends ActivityInstrumentationTestCase2<NotesList>{

    private Solo solo;
    public NotePadtest() {
    super("com.example.android.notepad", NotesList.class);
    }

    public void setUp() throws Exception {
    solo = new Solo(getInstrumentation(), getActivity());
    }

    @Smoke
    public void testAddNote() throws Exception {
    solo.clickOnMenuItem("Add note");
    //Assert that NoteEditor activity is opened
    solo.assertCurrentActivity("Expected NoteEditor activity", "NoteEditor");
    //In text field 0, add Note 1
    solo.enterText(0, "老郭的第一个测试 ");
    solo.goBack();
    //Clicks on menu item
    solo.clickOnMenuItem("Add note");
    //In text field 0, add Note 2
    solo.enterText(0, "老郭的第二个测试 ");
    //Go back to first activity named "NotesList"
    solo.goBackToActivity("NotesList");
    //solo.goBackToActivity("NotesList");
    boolean expected = true;
    boolean actual = solo.searchText("老郭的第一个测试 ") && solo.searchText("老郭的第二个测试 ");
    //Assert that Note 1 & Note 2 are found
    assertEquals("Note 1 and/or Note 2 are not found", expected, actual);
    System.out.println("添加功能测试的实际结果是:"+actual+"  "+"预期结果是:"+expected);

    }
       
    @Smoke
    public void testEditNote() throws Exception {
    // Click on the second list line
    solo.clickInList(2);
    // Change orientation of activity
    solo.setActivityOrientation(Solo.LANDSCAPE);
    // Change title
    solo.clickOnMenuItem("Edit title");
    //In first text field (0), add test
    solo.enterText(0, " test"); 
    solo.goBackToActivity("NotesList");
    boolean expected = true;
    // (Regexp) case insensitive
    boolean actual = solo.searchText("老郭的(?i).*? test");
    //Assert that Note 1 test is found
    assertEquals("Note 1 test is not found", expected, actual);
    System.out.println("编辑功能测试的实际结果是:"+actual+"  "+"预期结果是:"+expected);


    }

    @Smoke
    public void testRemoveNote() throws Exception {
    //(Regexp) case insensitive/text that contains "test"
    solo.clickOnText("(?i).*?test.*");
    //Delete Note 1 test
    solo.clickOnMenuItem("Delete");
    //Note 1 test & Note 2 should not be found
    boolean expected = false;  
    boolean actual = solo.searchText("(?i).*?test.*");
    //Assert that Note 1 test is not found
    assertEquals("Note 1 Test is found", expected, actual); 
    solo.clickLongOnText("老郭的第二个测试");
    //Clicks on Delete in the context menu
    solo.clickOnText("(?i).*?Delete.*"); 
    actual = solo.searchText("老郭的第二个测试 ");
    //Assert that Note 2 is not found
    assertEquals("Note 2 is found", expected, actual); 
    System.out.println("删除功能测试的实际结果是:"+actual+"  "+"预期结果是:"+expected);
    }

    @Override
    public void tearDown() throws Exception {
    try {
    //Robotium will finish all the activities that have been opened
    solo.finalize();
    } catch (Throwable e) {
    e.printStackTrace();
    }
    getActivity().finish();
    super.tearDown();
    }
    }

    需要注意的地方:

    要做一点修改。 因为noteslist是在androidV21开发的,而我的测试代码是V23的。我们最好要改成一致的。

    修改 noteslisttest 下的AndroidManifest.xml

    <uses-sdk android:minSdkVersion="9" />

    改成<uses-sdk android:minSdkVersion="7" />

    这两个数字表示什么意思呢?

    7--androidV21,9--androidV23,最低版本是3--AndroidV15.

    大家按顺序排就知道哪个数字对应的版本了

    然后在 noteslisttest 右击选中Properties--Android,选中AndroidV21

    这样noteslisttest 里带的android jar 由android2.3 变为android2.1

    再说一个配置,我觉得也很重要

    还是在AndroidManifest.xml 里

    <instrumentation android:targetPackage="com.example.android.notepad" android:name="android.test.InstrumentationTestRunner" /> 

    红色加粗的字符串表示我们要测试代码的package

    测试代码讲解:

    下面我们看看 noteslisttest 里的具体代码,看看它是怎么测试的

    // 告知系统我要测试的app是什么

     

    public NotePadTest() {

    super("com.example.android.notepad", NotesList.class);

    }

    //打开noteslist

    public void setUp() throws Exception {

    solo = new Solo(getInstrumentation(), getActivity());

    }

    public void testAddNote() throws Exception {

    solo.clickOnMenuItem("Add note");

    //Assert that NoteEditor activity is opened

    solo.assertCurrentActivity("Expected NoteEditor activity", "NoteEditor");

    //In text field 0, add Note 1

    solo.enterText(0, "Note 1");

    solo.goBack();

    //Clicks on menu item

    solo.clickOnMenuItem("Add note");

    //In text field 0, add Note 2

    solo.enterText(0, "Note 2");

    //Go back to first activity named "NotesList"

    solo.goBackToActivity("NotesList");

    boolean expected = true;

    boolean actual = solo.searchText("Note 1") && solo.searchText("Note 2");

    //Assert that Note 1 & Note 2 are found

    assertEquals("Note 1 and/or Note 2 are not found", expected, actual);

    }

    这是我们第一个case,主要目的是测试添加文本的功能

    clickOnMenuItem(String)

    功能是点击Menu按钮,选择文本描述为String的菜单,如我们的例子是"Add note"

    assertCurrentActivity(String message,String name)

    这个是判断当前的activity是否和我预期的一致

    message是描述性的文字

    name是指activity的名字

    关于如何知道activity 名字,我找了半天的文档,目前的方法是得看源码中的 AndroidManifest.xml--Application label--Application Nodes,在那里我们可以看到所有的activity的name

    enterText(int index,string text)

    index用来标识写到哪个EditText中。如果当前只打开一个EditText,那index=0

    text:就是我们要写入的内容

    goBack()

    相当于手机上的 返回键(back key)

    goBackToActivity(String name)

    返回到指定的activity

    searchText(String text)

    在当前的activity中搜索是否含有text的内容

    public void testEditNote() throws Exception {

    // Click on the second list line

    solo.clickInList(2);

    // Change orientation of activity

    solo.setActivityOrientation(Solo.LANDSCAPE);

    // Change title

    solo.clickOnMenuItem("Edit title");

    //In first text field (0), add test

    solo.enterText(0, " test"); 

    solo.goBackToActivity("NotesList");

    boolean expected = true;

    // (Regexp) case insensitive

    boolean actual = solo.searchText("(?i).*?note 1 test");

    //Assert that Note 1 test is found

    assertEquals("Note 1 test is found", expected, actual);

    }

    第二个case,主要是测试编辑功能的

    clickInList(int index)

    点击list表的第index行,进入该文本界面

    solo.setActivityOrientation(Solo.LANDSCAPE);

    setActivityOrientation,设置手机屏幕显示方式

    LANDSCAPE:横向显示

    Portrait:竖向显示

    public void testRemoveNote() throws Exception {

    //(Regexp) case insensitive/text that contains "test"

    solo.clickOnText("(?i).*?test.*");

    //Delete Note 1 test

    solo.clickOnMenuItem("Delete");

    //Note 1 test & Note 2 should not be found

    boolean expected = false;  

    boolean actual = solo.searchText("Note 1 test");

    //Assert that Note 1 test is not found

    assertEquals("Note 1 Test is not found", expected, actual); 

    solo.clickLongOnText("Note 2");

    //Clicks on Delete in the context menu

    solo.clickOnText("(?i).*?Delete.*"); 

    actual = solo.searchText("Note 2");

    //Assert that Note 2 is not found

    assertEquals("Note 2 is not found", expected, actual); 

    }

    第三个case,是用来测试删除功能的

    clickOnText(String text)

    点击包含该文字的地方

    其中text可以用正则表达式表示

    (?i)----忽略大小写。默认情况是大小写敏感的。

    正则表达式与java保持一致

    clickLongOnText(String text)

    长时间按住所选的文字

    例子看上去还比较简单。学了几个函数方法。

     

    /实例3/

    创建一个简单的工程(可参考本人的日志《第一个应用HelloWorld》,需要对该工程稍做修改)作为被测程序,运行后显示如下界面

    2.     创建一个Test Project

    1).    打开eclipse,选择File->New->Project…->Android Test Project,点击Next

    2).    Test Project Name中输入测试工程的名称,如:HelloWorldTest。选择An existingAndroid Project,点击右边的Browse…按钮。

    3).    选择被测工程,如之前创建的HelloWorldnp,点击OK按钮。

    4).    会自动选择和输入Build TargetProperties,可以按照默认的,不用修改。

    5).    一个新建的测试工程(HelloWorldTest)就创建好了,如下图:

    3.     创建一个Test Case

    1).    HelloWorldTest->src->com.liliandroid.helloworld.test上,右击选择New->Class,创建一个Test Case

    2).    Name中输入Test Case的名字,如:UITextTest

    3).    创建好的Test Case如下图:

    4.     导入robotium.jar

    1).    选择测试工程HelloWorldTest右击,选择Build Path->Configure Build Path…

    2).    在打开的Properties for HelloWorldTest中点击Add External JARs…按钮。

    3).    因为之前创建的工程的SDK2.2的,所以选择robotium-solo-1.8.0.jar

    4).    点击OK按钮。

    5.     修改Test Case

    打开UITextTest.java,输入以下内容并保存:

    packagecom.liliandroid.helloworld.test;

    importandroid.test.ActivityInstrumentationTestCase2;

    importcom.liliandroid.helloworld.ActivityMain;

    importcom.jayway.android.robotium.solo.Solo;

    publicclassUITextTestextendsActivityInstrumentationTestCase2<ActivityMain>{

         privateSolosolo;

         publicUITextTest() {

             super("com.liliandroid.helloworld", ActivityMain.class);

              }

             

         publicvoidsetUp()throwsException {

             solo=newSolo(getInstrumentation(), getActivity());

                 }

                

         publicvoidtestUI()throwsException {

             booleanexpected =true;

             booleanactual =solo.searchText("This") &&solo.searchText("is");

              assertEquals("This and/or is are not found", expected, actual);

             

          }

      

    }

    注:这个Case是测试运行了ActivityMain后的界面上是否有Thisis这两个文字。

    6.     运行测试程序

    选择测试工程HelloWorldTest右击,选择Run As->AndroidJUnit Test运行测试程序

    运行完后的测试结果界面(Pass

    运行完后的测试结果界面(Fail

    注:

    1.     被测试的工程和测试的工程可以是不同的SDK,但是不知道有什么影响。

    2.     这是在eclipse中进行测试的,也可以在模拟器或者手机上测试。如果需要直接在模拟器或者手机上测试,需要将测试包和被测试包改成相同的签名。(关于apk包的签名和重签名,请参考本人日志《重新签名APK文件》)

     

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值