Android 单元测试(junit、mockito、robolectric)
2016-08-16 17:43
477 查看
1、运用JUnit4 进行单元测试
首先在工程的
打开工程的
build.gradle
(1)新建被测类:
(2)新建测试类:
这时候 右键 - testSum()方法,选择选择Run > testRun , 也可以通过命令行运行测试,在工程目录内输入:
这时测试因为我写被测类的时候,返回的是0,所以跟期望的值不一样,就会失败。
这时,我们修改下Calculator.java的函数:
保存,这时候再运行测试,成功,跟期望值一样。
总结:位于
编写测试,实现功能使测试通过,然后再添加更多的测试,这种工作方式使快速迭代成为可能,我们称之为测试驱动开发。
2、使用Mockito等mocking框架来mock测试。
Mock:
mock对象就是在调试期间用来作为真实对象的替代品。
mock测试就是在测试过程中,对那些不容易构建的对象用一个虚拟对象来代替测试的方法就叫mock测试。
打开工程的
build.gradle
关于mokito的使用,官网已经给出很详细了。我这里主要想记录下主要用到的。对于mvp架构下,测试presenter返回到view的数据,是否正确。
配合mvp模式下,利用本地json,模仿网络请求,进行模拟数据,查看presenter 处理逻辑是否正确。
get_list.json 是放到 src/test下的assets 目录下,这个目录在:打开工程的
其他的用法:参考下官方就行,因为官网是英文的,看不懂的,还可以前往:Mockito 中文文档
3、使用Robolectric
Robolectric 是一个针对于Android SDK 的单元测试框架,使用它可以测试驱动你的Android应用程序的开发。测试用例只需要在JVM基础上就能运行起来。
打开工程的
build.gradle
1、创建一个WelcomeActivity, 点击登录,跳转到登录页面。
布局文件:
Activity:
测试的是:当用户点击登陆按钮后,我们启动了正常的intent。
由于Robolectric只是一个模拟的单元测试框架,LoginActivity并不会真正的启动,但是我们可以检查是否准确的发出了WelcomActivity的intent。
判断点击后textview 文本变化是否正常等:
对于控制activity的生命周期,Robolectric 2.2版本以后增加了控制activity方法:
这会创建一个WelcomeActivity,并且已经调用了onCreate()。
(1)检查一些在onCreate()和onResume()之间发生的事件:
(2)完整的生命周期:
(3)使用intent 来启动activity:
(4)保存状态:
首先在工程的
src文件夹内创建
test和
test/java文件夹。
打开工程的
build.gradle(Module:app)文件,添加JUnit4依赖,点击Gradle sync按钮。
build.gradle
dependencies { testCompile 'junit:junit:4.12' }
(1)新建被测类:
public class Calculator { public double sum(double a, double b){ // 假设先返回结果0 return 0; } }
(2)新建测试类:
import org.junit.Before; import org.junit.Test; import static org.junit.Assert.*;
public class CalculatorTest { private Calculator mCalculator; @Before public void setUp() throws Exception { mCalculator = new Calculator(); } @Test public void testSum() throws Exception { //断言:1+1 = 2 assertEquals(mCalculator.sum(1d, 1d), 2d); } }
这时候 右键 - testSum()方法,选择选择Run > testRun , 也可以通过命令行运行测试,在工程目录内输入:
./gradlew test
这时测试因为我写被测类的时候,返回的是0,所以跟期望的值不一样,就会失败。
这时,我们修改下Calculator.java的函数:
public double sum(double a, double b){ return a + b; }
保存,这时候再运行测试,成功,跟期望值一样。
总结:位于
src/tests目录下的测试是运行在本地电脑Java虚拟机上的单元测试。
编写测试,实现功能使测试通过,然后再添加更多的测试,这种工作方式使快速迭代成为可能,我们称之为测试驱动开发。
2、使用Mockito等mocking框架来mock测试。
Mock:
mock对象就是在调试期间用来作为真实对象的替代品。
mock测试就是在测试过程中,对那些不容易构建的对象用一个虚拟对象来代替测试的方法就叫mock测试。
打开工程的
build.gradle(Module:app)文件,添加Mockito依赖,点击Gradle sync按钮。
build.gradle
dependencies { // 单元测试 testCompile 'org.mockito:mockito-all:2.0.2-beta' testCompile 'junit:junit:4.12' }
关于mokito的使用,官网已经给出很详细了。我这里主要想记录下主要用到的。对于mvp架构下,测试presenter返回到view的数据,是否正确。
配合mvp模式下,利用本地json,模仿网络请求,进行模拟数据,查看presenter 处理逻辑是否正确。
public class PresenterTest { @Mock Repository repository; // 网络请求 @Mock View view; // view PresenterImpl presenter; @Before public void setUp() throws Exception { // 如果有使用到rxjava,可以在这里处理rxjava变成同步执行 MockitoAnnotations.initMocks(this); presenter = new PresenterImpl(view, repository); } @Test public void getOrderList() throws Exception{ String json = readAssetsJSON("get_list.json").optString("data"); List<ViewModel> list = JSON.parseArray(json, ViewModel.class); when(repository.getList(1)).thenReturn(Observable.just(list)); presenter.getList(1); ArgumentCaptor<ArrayList> captor = ArgumentCaptor.forClass(ArrayList.class); verify(presenter.getView()).onGetDataByFinish(captor.capture()); List<ViewModel> viewModels = captor.getValue(); assertEquals(list.size(), viewModels.size()); } }
get_list.json 是放到 src/test下的assets 目录下,这个目录在:打开工程的
build.gradle(Module:app)文件,android节点下的sourceSets节点下,配置下:
sourceSets {
main {
.....
}
test{
java.srcDirs = [ 'src/test/java']
}
}
其他的用法:参考下官方就行,因为官网是英文的,看不懂的,还可以前往:Mockito 中文文档
3、使用Robolectric
Robolectric 是一个针对于Android SDK 的单元测试框架,使用它可以测试驱动你的Android应用程序的开发。测试用例只需要在JVM基础上就能运行起来。
打开工程的
build.gradle(Module:app)文件,添加Robolectric依赖,点击Gradle sync按钮。
build.gradle
dependencies { // 单元测试 testCompile 'org.robolectric:robolectric:3.1-rc1' testCompile 'org.mockito:mockito-all:2.0.2-beta' testCompile 'junit:junit:4.12' }
1、创建一个WelcomeActivity, 点击登录,跳转到登录页面。
布局文件:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <Button android:id="@+id/btn_login" android:text="click the btn" android:layout_width="wrap_content" android:layout_height="wrap_content"/> </LinearLayout>
Activity:
public class WelcomeActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.welcome_activity); final View button = findViewById(R.id.btn_login); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { startActivity(new Intent(getContext(), LoginActivity.class)); } }); } }
测试的是:当用户点击登陆按钮后,我们启动了正常的intent。
由于Robolectric只是一个模拟的单元测试框架,LoginActivity并不会真正的启动,但是我们可以检查是否准确的发出了WelcomActivity的intent。
@RunWith(RobolectricTestRunner.class) public class WelcomeActivityTest { @Test public void clickingLogin_shouldStartLoginActivity() { WelcomeActivity activity = Robolectric.setupActivity(WelcomeActivity.class); activity.findViewById(R.id.btn_login).performClick(); Intent expectedIntent = new Intent(activity, WelcomeActivity.class); assertThat(shadowOf(activity).getNextStartedActivity()).isEqualTo(expectedIntent); } }
判断点击后textview 文本变化是否正常等:
@RunWith(RobolectricTestRunner.class) public class WelcomeActivityTest { @Test public void clickLoginButton() throws Exception { Activity activity = Robolectric.buildActivity(WelcomeActivity.class).create().get(); Button btn_login = (Button) activity.findViewById(R.id.btn_login); TextView tv_result = (TextView) activity.findViewById(R.id.tv_result); btn_login.performClick(); String resultsText = tv_result.getText().toString(); assertThat(resultsText, equalTo("Click the login button")); } }
对于控制activity的生命周期,Robolectric 2.2版本以后增加了控制activity方法:
Activity activity = Robolectric.buildActivity(WelcomeActivity.class).create().get();
这会创建一个WelcomeActivity,并且已经调用了onCreate()。
(1)检查一些在onCreate()和onResume()之间发生的事件:
ActivityController controller = Robolectric.buildActivity(WelcomeActivity.class).create().start(); Activity activity = controller.get(); // assert that something hasn't happened activityController.resume();
(2)完整的生命周期:
Activity activity = Robolectric.buildActivity(WelcomeActivity.class).create().start().resume().visible().get();
(3)使用intent 来启动activity:
Intent intent = new Intent(Intent.ACTION_VIEW); Activity activity = Robolectric.buildActivity(WelcomeActivity.class).withIntent(intent).create().get();
(4)保存状态:
1 Bundle savedInstanceState = new Bundle(); 2 savedInstanceState.putExtra("user_age", "18"); 3 savedInstanceState.putExtra("user_name", "jay"); 4 Activity activity = Robolectric.buildActivity(WelcomeActivity.class).create() 5 .restoreInstanceState(savedInstanceState).get();
相关文章推荐
- 【Android】——单元测试、JUnit4、Mockito、Dagger2等
- JUnit + Mockito 单元测试(二)
- Android-使用Mockito、Robolectric和RxJava及Retrofit进行单元测试
- JUnit + Mockito 单元测试(三)
- 基于Springboot+Junit+Mockito做单元测试的示例
- JUnit + Mockito 单元测试(二)(good)
- SpringBoot与JUnit+Mockito 单元测试
- JUnit + Mockito 单元测试
- Android 单元测试 Mockito使用详解
- 单元测试系列三-基于Springboot+Junit+Mockito做单元测试
- 单元测试及框架简介 --junit、jmock、mockito、powermock的简单使用
- JUnit + Mockito 单元测试(一)
- Mockito入门及配合Junit进行单元测试
- JUnit + Mockito 单元测试(二)
- JUnit + Mockito 单元测试
- JUnit/Mockito实现单元测试
- JUnit + Mockito 单元测试(二)
- 单元测试及框架简介 --junit、jmock、mockito、powermock的简单使用
- Android单元测试(二):Mockito框架的使用
- 在Android上实现Junit单元测试的四部曲