目前用于Android的测试框架已经有很多,比如:Monkey、Appium和Robotium等。Monkey这是大家比较熟悉的,Android自带的系统工具。Monkey通过向系统发送伪随机的用户事件流(如按键输入、触摸屏输入、手势输入等),实现对正在开发的应用程序进行压力测试,是用于测试软件的稳定性、健壮性的快速有效的方法。.Appium测试相当于黑盒测试。这个测试框架,一般用于测试UI逻辑的正确性,不能升入测试业务逻辑流程。

Robotium是一款面向Android端的开源自动化测试框架,Robotium结合Android自身提供的测试框架可以对应用程序进行自动化测试。另外,Robotium还支持对WebView的操作。Robotium的核心类是Solo,通过Solo可以对控件进行各种操作。

环境配置

  1. 开发工具使用AndroidStudio,AndroidStudio的Junit版本是4.12,可以支持参数化测试。

  2. 在androidTest包下测试代码,AndroidStudio重新划分了工程的结构,分为androidTest、main、test三个文件夹,其中androidTest为Instrmentation测试包,main为源码包,test为单元测试包。Robotium是基于Instrmentation的测试框架,所以我们在这个包内写测试代码。

  3. 修改build.gradle

defaultConfig {    applicationId cfg.package    minSdkVersion cfg.minSdk    targetSdkVersion cfg.targetSdk    versionCode cfg.version_code    versionName cfg.version_name    testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"}dependencies {    compile fileTree(include: ['*.jar'], dir: 'libs')    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {        exclude group: 'com.android.support', module: 'support-annotations'    })    androidTestCompile 'com.android.support.test:rules:0.4.1'    compile 'com.jayway.android.robotium:robotium-solo:5.6.0'}

注:注意这里testInstrumentationRunner使用的是android.support.test.runner.AndroidJUnitRunner而不是android.test.InstrumentationTestRunner.

编写case代码

  • 通过@RunWith实现

通过使用@RunWith(AndroidJUnit4.class)注解不需要再继承ActivityInstrumentationTestCase2类,如果需要参数化执行可修改为@RunWith(Parameterized.class)。很明显这种方式是基于Junit4实现的。

setUp()做一些启动测试前的准备工作,如创建Solo实例,启动Activity等。

@Beforepublic void setUp() throws Exception {    solo = new Solo(InstrumentationRegistry.getInstrumentation(),            activityTestRule.getActivity());}

tearDown()中测试做一些善后的工作,如结束Activity等

@Afterpublic void tearDown() throws Exception {    solo.finishOpenedActivities();}

上述工作准备好之后,剩下的就是我们的测试主体方法了。为了方便主体方法一般以test开头。

@Testpublic void testLogin() throws Exception {    AutoCompleteTextView name = (AutoCompleteTextView) solo.getView("atv_scarid");    EditText pwd = (EditText) solo.getView("et_pwd");    solo.enterText(name, "cnsldg");    solo.enterText(pwd, "666888");    solo.clickOnView(solo.getView("bt_login"));}

整体结构如下:

@RunWith(AndroidJUnit4.class)public class LoginAcitityTest {    @Rule    public ActivityTestRule activityTestRule =            new ActivityTestRule<>(LoginActivity.class);    private Solo solo;    @Before    public void setUp() throws Exception {        solo = new Solo(InstrumentationRegistry.getInstrumentation(),                activityTestRule.getActivity());    }    @After    public void tearDown() throws Exception {        solo.finishOpenedActivities();    }    @Test    public void testLogin() throws Exception {        AutoCompleteTextView name = (AutoCompleteTextView) solo.getView("atv_scarid");        EditText pwd = (EditText) solo.getView("et_pwd");        solo.enterText(name, ""); //清空        solo.enterText(pwd, ""); //清空        solo.enterText(name, "cnsldg");        solo.enterText(pwd, "666888");        solo.clickOnView(solo.getView("bt_login"));        boolean result = solo.waitForActivity(HistoryActivity.class, 1000);        Assert.assertEquals(true, result);    }}

在测试方法上右键点击运行

  • 通过继承ActivityInstrumentationTestCase2类实现,这种方式基于Junit3比较老,已经被标注为@Deprecated不建议使用。
public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActivity> {    private Solo solo;    public MainActivityTest() {        super(MainActivity.class);    }    @Override    protected void setUp() throws Exception {        super.setUp();        solo = new Solo(getInstrumentation(), getActivity());    }    @Override    protected void tearDown() throws Exception {        solo.finishOpenedActivities();        super.tearDown();    }    public void testAdd()    {        EditText et_num1 = (EditText) solo.getView("et_num1");        EditText et_num2 = (EditText) solo.getView("et_num2");        solo.enterText(et_num1, "1");        solo.enterText(et_num2, "2");        Button btn = (Button) solo.getView("btn");        TextView tv_sum = (TextView) solo.getView("tv_sum");        solo.clickOnView(btn);        //等待点击事件生效        solo.sleep(200);        assertEquals("3", tv_sum.getText().toString());    }}

注意:测试代码并不是在主线程运行的,所以我们不能直接通过获取View来更改UI

Solo类

  • 获取控件
getView(int id)getView(int id, int index) //index表示控件是界面上第几个相同控件getView(String id) //xml中定义的id属性值
  • 验证TextView文字
TextView textView = (TextView)solo.getView("hello");assertEquals("hello world", textView.getText().toString());
  • 输入文本
//先获取控件,enterText(EditText editText, String text)//index表示页面上的第几个输入框enterText(int index, String text)
  • 等待对话框关闭和打开
waitForDialogToClose()waitForDialogToClose(long timeout)waitForDialogToOpen()waitForDialogToOpen(long timeout)

long timeout:设置超时时间,单位为毫秒

  • 验证Activity的加载
//等待指定Activity的出现waitForActivity(String)waitForActivity(String, int)waitForActivity(Class<? extends Activity)waitForActivity(Class<? extends Activity, int)

String:Activity名称
int:超时时间,默认为20000,单位为毫秒
Class

//休眠指定时间sleep(int time)//从当前界面搜索指定的文本searchText(String text)//等待指定Log的出现waitForLogMessage(String logMessage)//等待控件的出现waitForView(int id)//等待文本的出现waitForText(String text)//等待某种加载条件的达成boolean waitForCondition (Condition condition, int timeout)
  • 滚动滑动操作
//滑动到顶部scrollTop()//向上向下滚动屏幕scrollUp()/scorllDown()//滚动至ListView第line行scrollListToLine(AbsListView absListView, int line)//从其实x,y左边滑动至终点x,y坐标drag(float fromX, float toX, float fromY, from toY)
  • 其他操作
//截图,name为图片的参数,默认路径是/sdcard/Robotium-Screenshots/takeScreenshot()takeScreenshot(String name)//截取某段时间内一个序列takeScreenshotSequence(String name)//关闭当前已打开的所有ActivityfinishOpenedActivities()//点击返回键goBack()//不断点击返回键直至返回到指定ActivitygoBackToActivity(String name)// 收起键盘hideSoftKeyboard()//设置Activity转屏方向setActivityOrientation(int orientation)

更多相关文章

  1. android-【机型-版本-分辨率】测试点罗列
  2. Mediapipe框架在Android上的使用
  3. QADDroid—android快速原型框架
  4. Android使用xutils3框架实现应用程序内的检查更新下载服务器存放
  5. Android:单元测试Junit的配置
  6. android 常用测试框架
  7. Android ListView:实现item内部控件的点击事件
  8. android: 静态XML和动态加载XML混合使用,以及重写Layout控件

随机推荐

  1. SQL中exists的使用方法
  2. SQLServer中的切割字符串SplitString函数
  3. 用SQL语句添加删除修改字段、一些表与字
  4. mssql存储过程表名和字段名为变量的实现
  5. 通过T-SQL语句实现数据库备份与还原的代
  6. SQL Server 自动增长清零的方法
  7. sqlserver 临时表 Vs 表变量 详细介绍
  8. 卸载VS2011 Developer Preview后Sql Serv
  9. 自动定时备份sqlserver数据库的方法
  10. 扩展性很好的一个分页存储过程分享