关于单元测试,第一次接触是帮学长翻译 Mockito 中文文档。说来惭愧,当时对 Mockito 和单元测试都了解甚少,硬着头皮翻译效果很差。今天开始了解下单元测试相关的内容。
Android 的单元测试可以分为两种,运行在本地的 local unit tests 和需要实机的 instrumented tests 。新建一个Android项目,可以看到其测试相关目录结构如下图:
Local unit tests (test)
- 相关文件位于
module-name/src/test/java/
. - Building Local Unit Tests.
Instrumented tests (androidTest)
- 相关文件位于
module-name/src/androidTest/java/
. - Building Instrumented Unit Tests:用于测试某些依赖于 Android,简单的 mock 不适用的场景.
- Automating User Interface Tests:用于测试 UI 行为是否正确.
- Building Instrumented Unit Tests:用于测试用户不能直接操作的组件行为,比如
Service
和ContentProvider
.
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
44public class ExampleUnitTest {
public static void beforeClass() {
// 一个静态方法,只在最开始执行一次,可以用于数据库
// 连接等资源消耗严重的操作。
}
public void setup() {
// 一般用于初始化测试用例数据,可以有多个 @Before 修饰
// 的方法,但不能保证它们之间调用的顺序。
}
public void addition_isCorrect() throws Exception {
// 测试用例
assertEquals(4, 2 + 2);
}
public void addition_args() throws Exception {
// 可以设定某些参数 timeout/expected
ArrayList emptyList = new ArrayList();
Object o = emptyList.get(0);
}
public void hopeException(){
// @Ignore 可以忽略某个测试用例
List a = null;
a.get(0);
}
public void teardown() {
// 用于释放资源相关操作,和 @Before 一样可以定义多个。
}
public static void afterClass() {
// 可以用来释放 @BeforeClass 初始化的资源。
}
}
Mockito
Mockito 是一个非常强大的工具。它可以 mock 对象、验证结果以及 stub 方法调用。
1 | public class MockitoSimpleText { |
others
Clean Code 介绍单元测试时提到结构清晰的测试用例要遵循 BUILD-OPERATE-CHECK 模式。1
2
3
4
5
6
7
8public void testGetDataAsXml() throws Exception {
makePageWithContent("TestPageOne", "test page");
submitRequest("TestPageOne", "type:data");
assertResponseIsXML();
assertResponseContains("test page", "<Test");
}
参考文档: