robolectric

2015/8/15 posted in  Android

环境搭建

环境 : Android Studio 1.2.1.1+ Android Gradle Plugin 1.2.3+ Gradle 2.2.1+

gradle中加入:

  dependencies {
    ...
    testCompile 'org.robolectric:robolectric:3.0'
  }

确认在Build Variants窗口内的Test Artifact中选择了"Unit Tests"。

然后,在工程的src文件夹内创建test和test/java文件夹。需要注意的是,你不能在Android视图下进行这些操作,要么在系统的文件管理器内创建,要么在工程窗口左上方点击下拉菜单选择Project视图。最终的工程结构应该是这样的:

配置成功之后java文件夹的颜色是绿色的

**重要重要**
Run -> Edit Configurations -> Defaults -> Junit
设置如下 \(MODULE_DIR\).

gradle 同步

注意Robolectric目前不支持android 5.1 API level 22,编译时 sdk = 21 或者以下。

单元测试写法

@Config(constants = BuildConfig.class)
记得加入

//省略import
@RunWith(RobolectricGradleTestRunner.class)

public class MainActivityTest {
    private MainActivity activity;

    @Before
    public void setup() throws Exception {
        //执行初始化操作
    }

    @Test
    public void validateTextViewContent() throws Exception {
         //执行各种测试逻辑判断
        }

Activity

Activity的创建

Activity activity = Robolectric.buildActivity(MyAwesomeActivity.class).create().get();

会创建一个MyAwesomeActivity实例,然后调用它的onCreat()方法

如果只想验证其onResume()方法,可以如下

ActivityController controller = Robolectric.buildActivity(MyAwesomeActivity.class).create().start();
Activity activity = controller.get();
// assert that something hasn't happened
activityController.resume();
// assert it happened!

如果想测试整个activity 的生命周期可以

Activity activity = Robolectric.buildActivity(MyAwesomeActivity.class).create().start().resume().visible().get();

等你需要在activity中,对view进行一些操作时候,比如Robolectric.clickOn(),这时候你需要在create()后加入visible()

举例

我在工程中建立了三个Activity分别为 MainActivity,AnotherActivity,ThridActivity
在MainActivity加入按键跳转到AnotherActivity中,

   public void startAnotherActivity(View view) {
        startActivity(new Intent(MainActivity.this, AnotherActivity.class));
    }

增加单元测试用例判断跳转的是否正确

    @Test
    public void clickingLogin_shouldStartLoginActivity() {
        Button button = (Button) activity.findViewById(R.id.button);
        assertTrue(button.isEnabled());
        button.performClick();

        Intent expectedIntent = new Intent(activity, ThridActivity.class);
        assertEquals(expectedIntent,shadowOf(activity).getNextStartedActivity() );

    }

1.通过 activity.findViewById 找到button
2.判断button是否可以点击
3.点击button
4.构造一个intent(从MainActivity跳转到ThridActivity)
5.判断实际跳转的和构造的是否一直

结构不一致报错

java.lang.AssertionError: 
Expected :Intent{componentName=ComponentInfo{io.github.xuyushi.robolectric/io.github.xuyushi.robolectric.ThridActivity}, extras=Bundle[{}]}
Actual   :Intent{componentName=ComponentInfo{io.github.xuyushi.robolectric/io.github.xuyushi.robolectric.AnotherActivity}, extras=Bundle[{}]}
 <Click to see difference>
    at org.junit.Assert.fail(Assert.java:91)
    at org.junit.Assert.failNotEquals(Assert.java:645)
    at org.junit.Assert.assertEquals(Assert.java:126)
    at org.junit.Assert.assertEquals(Assert.java:145)

可以很清楚的定位到错误

Dialog验证

Toast验证

response写法

Shodaw

参考

http://hkliya.gitbooks.io/unit-test-android-with-robolectric/content/2-api-explained.html
http://robolectric.org
http://chriszou.com/android-unit-testing-with-robolectric