美文网首页
android 单元测试

android 单元测试

作者: 子墨_guo | 来源:发表于2018-02-05 10:47 被阅读60次

单元测试的重要的和必要性这里不在强调,本文介绍几个常用的单元测试的框架

JUnit4

JUnit4是一个java的单元测试框架,多数Java的开发环境都已经集成了JUnit作为单元测试的工具,android studio默认继承了JUNit4

testImplementation 'junit:junit:4.12'

JUnit4主要是通过注解的方式来识别测试方法,下面介绍几个常用的方法以及它的作用:

  • @BeforeClass 在执行所有测试方法之前执行,只执行一次,对应方法必须是静态方法
  • @Before 在任意使用@Test注解标注方法执行之前执行
  • @Test 测试方法
  • @After 在任意使用@Test注解标注方法执行之后执行
  • @AfterClass 在执行所有测试方法之后执行,只执行一次,对应方法必须是静态方法

了解完以上的信息还没有完结,单元测试还有很重要的一点验证结果,一般是通过一些assert方法来完成的,JUnit为我们提供的assert方法,多数都在Assert这个类里面

  • Assert.assertEquals 验证执行结果与期盼结果比较,这个方法的参数有很多种,根据需要使用
  • Assert.assertFalse 验证参数为false
  • Assert.assertNotNull 验证参数不为空
  • Assert.assertNotSame 参数中的两个对象不是同一个对象
  • Assert.assertNull 验证参数为空
  • Assert.assertSame 参数中的两个对象是同一个对象
  • Assert.assertThat 实际情况满足匹配器给出的条件
  • Assert.assertTrue 验证参数为true

由于很多地方用到了Assert.assertThat方法,下面列一下啊Matcher常用的方法

  • Matcher.allOf
  • Matcher.anyOf
  • Matcher.both
  • Matcher.containsString
  • Matcher.describedAs
  • Matcher.either
  • Matcher.endsWith
  • Matcher.equalTo
  • Matcher.instanceOf
  • Matcher.is
  • Matcher.hasItem

JUnit单元测试时是不能使用Android相关的类的,下面就来认识一下Robolectric框架

Robolectric

Robolectric框架是针对android的测试框架,使用Robolectric框架进行单元测试不用依赖真机或者模拟器,Robolectric支持单元测试范围从Activity的跳转、Activity展示View(包括菜单)和Fragment到View的点击触摸以及事件响应,同时Robolectric也能测试Toast和Dialog。对于需要网络请求数据的测试,Robolectric可以模拟网络请求的response。对于一些Robolectric不能测试的对象,比如ConcurrentTask,可以通过自定义Shadow的方式现实测试。下面将着重介绍Robolectric的常见用法。

引入

testCompile "org.robolectric:robolectric:3.6.1"

官方给出的demo
<pre>
@RunWith(RobolectricTestRunner.class)
@Config(constants = BuildConfig.class)
public class MyActivityTest {

@Test
public void clickingButton_shouldChangeResultsViewText() throws Exception {
Activity activity = Robolectric.setupActivity(MyActivity.class);

Button button = (Button) activity.findViewById(R.id.press_me_button);
TextView results = (TextView) activity.findViewById(R.id.results_text_view);

button.performClick();
assertThat(results.getText().toString(), equalTo("Testing Android Rocks!"));

}
}
</pre>

@RunWith(RobolectricGradleTestRunner.class)表示用Robolectric的TestRunner来跑这些test,通过gradle CLI或者Android studio运行为单元测试定制的测试运行程序,有一条件必须配置@Config

@RunWith(RobolectricTestRunner.class)提供Android运行时的模拟环境

Robolectric框架通过shadow类替换对应的真实方法,最终实现测试脱离底层实现,感兴趣的话,可以自行了解

Mock

对于一些依赖关系复杂的测试对象,可以采用Mock框架解除依赖,常用的有Mockito,mock创建一个类的虚假的对象,用于解耦真实对象所需要的依赖,Mock得到的对象仅仅是具备测试对象的类型,并不是真实的对象,也就是并没有执行过真实对象的逻辑。

引入

repositories { jcenter() }
dependencies { testCompile "org.mockito:mockito-core:2.+" }

Mock的方法使用

// mock creation
List mockedList = mock(List.class);

// using mock object - it does not throw any "unexpected interaction" exception
mockedList.add("one");
mockedList.clear();

// selective, explicit, highly readable verification
verify(mockedList).add("one");
verify(mockedList).clear();

直接通过mock方法创建虚拟对象,也可以使用注解的方式 @Mock 来创建,通过 verify 方法来检查相应方法是否调用

stub形式的使用

// you can mock concrete classes, not only interfaces
LinkedList mockedList = mock(LinkedList.class);

// stubbing appears before the actual execution
when(mockedList.get(0)).thenReturn("first");

// the following prints "first"
System.out.println(mockedList.get(0));

// the following prints "null" because get(999) was not stubbed
System.out.println(mockedList.get(999));

指定关键字 when 返回一个 OngoingStubbing 接口,通过其提供的 thenReturn,thenThrow,thenCallRealMethod 及自定义 thenAnswer 来返回相应的结果

Mock中几个主要的方法

  • mock()/@Mock: 创建一个Mock虚拟对象
  • spy()/@Spy: 部分mock,真正的方法会被调用,但是仍然需要验证
  • verify(): 检测方法是否被调用

通过 times,never,atLeastOnce,atLeast,atMost 这些方法,我们可以对一个方法的调用次数做判断

verify(mockedList, atLeastOnce()).add("three times")

通过doThrow为一个方法的调用添加异常,验证代码对异常的处理

doThrow(new RuntimeException()).when(mockedList).clear();

通过Mockito的inOrder方法验证调用顺序

更多使用方法请参考mock官网

注:final类型、private类型以及静态类型的方法不能mock

总结

JUnit框架主要是用来测试java类的,既能做单元测试也能做集成测试,如果想要调用android的方法需要用到Robolectric框架,这两个框架可以做的事情很多,几乎能满足你所有的需求,但是有的时候测试需要用到虚拟对象,就需要用到Mock框架了。

希望这篇文章,对初次接触单元测试的你有所帮助

参考文献:

相关文章

网友评论

      本文标题:android 单元测试

      本文链接:https://www.haomeiwen.com/subject/ofijhttx.html