2016-09-17 | learn

Android 单元测试的简单介绍

示例项目

关于单元测试,第一次接触是帮学长翻译 Mockito 中文文档。说来惭愧,当时对 Mockito 和单元测试都了解甚少,硬着头皮翻译效果很差。今天开始了解下单元测试相关的内容。

Android 的单元测试可以分为两种,运行在本地的 local unit tests 和需要实机的 instrumented tests 。新建一个Android项目,可以看到其测试相关目录结构如下图:

Android Project Structure

Local unit tests (test)

Instrumented tests (androidTest)

JUnit

今天只说 local unit tests 。 Local unit tests 运行在本地 JVM 中,不依赖Android framework 。Android 项目默认包含 JUnit 框架。

1
testCompile 'junit:junit:4.12'

JUnit 提供了一系列方便的方法完成单元测试,可以通过写一段代码了解下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
public class ExampleUnitTest {
@BeforeClass
public static void beforeClass() {
// 一个静态方法,只在最开始执行一次,可以用于数据库
// 连接等资源消耗严重的操作。
}

@Before
public void setup() {
// 一般用于初始化测试用例数据,可以有多个 @Before 修饰
// 的方法,但不能保证它们之间调用的顺序。
}

@Test
public void addition_isCorrect() throws Exception {
// 测试用例
assertEquals(4, 2 + 2);
}

@Test(expected=IndexOutOfBoundsException.class)
public void addition_args() throws Exception {
// 可以设定某些参数 timeout/expected
ArrayList emptyList = new ArrayList();
Object o = emptyList.get(0);
}

@Ignore
@Test(expected = NullPointerException.class)
public void hopeException(){
// @Ignore 可以忽略某个测试用例
List a = null;
a.get(0);
}

@After
public void teardown() {
// 用于释放资源相关操作,和 @Before 一样可以定义多个。
}

@AfterClass
public static void afterClass() {
// 可以用来释放 @BeforeClass 初始化的资源。
}
}

Mockito

Mockito 是一个非常强大的工具。它可以 mock 对象、验证结果以及 stub 方法调用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
public class MockitoSimpleText {

@Test
public void mockitoExample() {
// mock 一个数据
List list = mock(List.class);
list.add("one");
Object o = list.get(0);

assertNotNull(list);
assertNull(o);
}

@Test
public void mockitoStub(){
// stub 方法调用
List list = mock(List.class);
when(list.get(0)).thenReturn("hey");

assertEquals("hey",list.get(0));
}

@Test
public void mockitoVerify(){
// 验证方法调用
List list = mock(List.class);
list.get(0);

verify(list).get(0);
}

// ...
}

others

Clean Code 介绍单元测试时提到结构清晰的测试用例要遵循 BUILD-OPERATE-CHECK 模式。

1
2
3
4
5
6
7
8
public void testGetDataAsXml() throws Exception {
makePageWithContent("TestPageOne", "test page");

submitRequest("TestPageOne", "type:data");

assertResponseIsXML();
assertResponseContains("test page", "<Test");
}

参考文档: