I. Android 中的单元测试
一. JUnit:java单元测试框架
在要测试的类中点击右键,选择 Go to > Test > create New Test … ,勾选setUp/@Before和tearDown/@After,勾选要测试的方法,然后OK创建测试类
在setUP方法中做初始化工作,在tearDown中做清理工作,在要测试的方法中写测试代码
在测试类中右键选 Run ‘测试类类名’ 来测试整个类,或选中要测试的方法,右键选 Run ‘方法名()’ 测试单个方法,或者在项目根目录运行 ./gradlew testDebugUnitTest 或者 ./gradlew testReleaseUnitTest 测试整个项目
junit库引入:
testCompile 'junit:junit:4.12'
更多用法查看:junit官方地址
一个例子:
要测试的类:Caculator
public class Caculator { public int add(int param1,int param2){ return param1+param2; } }
测试代码:CaculatorTest
public class CaculatorTest { Caculator caculator; @Before public void setUp() { caculator = new Caculator(); } @Test public void add() throws Exception { int result = caculator.add(1, 2); Assert.assertEquals(3, result); } @After public void tearDown() { caculator = null; } }
二. Mock:对象模拟框架
- 使用 Mockito.mock(clazz)可以得到一个模拟的clazz类型的对象
- 使用 Mockito.verify(objectToVerify).methodToVerify(arguments) 验证某个方法得到调用
- 要验证方法调用次数需在verify 方法中追加参数 Mockito.times(n),Mockito.atMost(n), Mockito.atLeast(n), Mockito.never() 等,如 Mockito.verify(objectToVerify,Mockito.times(n)).methodToVerify(arguments)
- Mockito提供了一系列的
any
方法,来表示任意参数,如 Mockito.anyString(),其他还有 anyInt, anyLong, anyDouble,anyObject,any(clazz),anyCollection,anyCollectionOf(clazz), anyList(Map, set), anyListOf(clazz) 等等。 - 指定mock对象的某个方法返回特定值用 Mockito.when(mockObject.targetMethod(args)).thenReturn(desiredReturnValue)。
指定mock对象执行特定的动作并伴随特地的返回结果处理用 Mockito.doAnswer(desiredAnswer).when(mockObject).targetMethod(args),其他还有 Mockito.doNothing(),Mockito.doThrow(desiredException),Mockito.doCallRealMethod() .
mockito 库引入
testCompile 'org.mockito:mockito-core:2.7.22' androidTestCompile 'org.mockito:mockito-android:2.7.22'
更多用法查看:mockito官方地址
一个例子:
public class Presenter { private Repo repo; public Presenter(Repo repo) { this.repo = repo; } public void getData(int id, String name) { if (id > 0 && name != null) { repo.optData(id, name); } else { repo.optError(id, name); } } } class Repo { public void optData(int id, String name) { Log.i("详情", "id:" + id + "-name:" + name); } public void optError(int id, String name) { Log.i("详情", "id:" + id + "-name:" + name); } }
测试代码:
public class PresenterTest { Repo repo; Presenter presenter; @Before public void setUp() throws Exception { repo = Mockito.mock(Repo.class); presenter = new Presenter(repo); } @Test public void getData() throws Exception { String name = "xiaoming"; int id = 123; presenter.getData(id, name); Mockito.verify(repo).optData(id, name); name = null; id = 0; presenter.getData(id, name); Mockito.verify(repo).optError(id, name); } @After public void tearDown() throws Exception { presenter = null; repo = null; } }
三. Robolectric:Android代码对象模拟框架
新建测试类,添加注解
@RunWith(RobolectricTestRunner.class)
其他配置,比如运行sdk版本,manifest文件等等可以通过下面注解配置
@Config(constants = BuildConfig.class,sdk=...,manifest=...)
使用 Robolectric.setupActivity(clazz) 可以得到一个模拟的clazz 类型的Activity对象
使用 Shadows.shadowOf(activity) 可以得到一个ShadowActivity 的实例
使用Shadows.shadowOf 还可以得到很多shadow对象,比如控件ShadowTextView,ShadowRecyclerView…,四大组件ShadowService,ShadowBroadcastReceiver…,System的Shadow类ShadowSystem…,基本上Android中的类都可以得到对应的Shadow对象。
执行测试 ./gradlew test
robolectric 库引入
testCompile "org.robolectric:robolectric:3.3.2"
更多用法查看:robolectric 官方地址
一个例子:public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); findViewById(R.id.tv_detail).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { startActivity(new Intent(MainActivity.this, DetailActivity.class)); } }); } }
测试代码:
@RunWith(RobolectricTestRunner.class) @Config(constants = BuildConfig.class) public class MainActivityTest { @Test public void testMainActivity(){ MainActivity mainActivity= Robolectric.setupActivity(MainActivity.class); mainActivity.findViewById(R.id.tv_detail).performClick(); Intent intent =new Intent(mainActivity,DetailActivity.class); ShadowActivity shadowActivity= Shadows.shadowOf(mainActivity); Assert.assertEquals(intent,shadowActivity.getNextStartedActivity()); } }
II.Android 中的UI测试
UI测试待续。。。。
更多详测试内容: