☰分类导航

软件工程/测试与发布
课程进度 83% · 第10/11章第10/11章 · 标签 1/6
— 1 —

单元测试(JUnit)

旧JUnit、Mockito和Espresso片段需对应测试依赖、宿主Activity及业务实现;登录固定账号仅为测试替身情境。原工具版本和签名命令是示例,不能直接替代项目发布配置或密钥管理。

单元测试用于验证独立模块的业务逻辑。Android 项目支持在 JVM 上运行的本地单元测试和在设备上运行的 Instrumented 测试。

先选一条真实规则,例如空标题不保存,再写输入、预期结果和副作用断言。2加2只是框架冒烟,不能证明业务正确;Mockito也应模拟可控依赖,而不是把每个方法都设为成功,导致错误处理路径从未被执行。


```java
@Test
public void testAddition() {
    assertEquals(4, 2 + 2);
}

// 使用 Mockito 模拟依赖
@Test
public void testLoginPresenter() {
    LoginView mockView = mock(LoginView.class);
    LoginPresenter presenter = new LoginPresenter(mockView);

    presenter.login("admin", "123456");

    verify(mockView).showLoading();
    verify(mockView).onLoginSuccess(anyString());
    verify(mockView, never()).onLoginError(anyString());
}
```
java
1
@Test
2
public void testAddition() {
3
assertEquals(4, 2 + 2);
4
}
5
 
6
// 使用 Mockito 模拟依赖
7
@Test
8
public void testLoginPresenter() {
9
LoginView mockView = mock(LoginView.class);
10
LoginPresenter presenter = new LoginPresenter(mockView);
11
 
12
presenter.login("admin", "123456");
13
 
14
verify(mockView).showLoading();
15
verify(mockView).onLoginSuccess(anyString());
16
verify(mockView, never()).onLoginError(anyString());
17
}

📖测试文件放在 src/test/java/ 目录下,使用 JUnit 4 + Mockito 进行单元测试

— 2 —

UI 自动化测试(Espresso)

Espresso 是 Google 官方 UI 测试框架,可模拟用户交互并验证界面状态。

UI测试要等待可观察的异步完成条件,不能用固定长睡眠掩盖竞争。验证按钮结果时还应核对任务身份与存储变化;设备、权限和动画状态会影响运行,因此每个用例应建立已知起点并清理自己创建的数据。


```java
// 点击按钮
onView(withId(R.id.btn_click)).perform(click());

// 检查文本
onView(withId(R.id.tv_hello))
    .check(matches(withText("Hello Android")));

// 输入文本
onView(withId(R.id.edit_input)).perform(typeText("测试输入"));

// 滚动列表并点击
onView(withId(R.id.recycler))
    .perform(RecyclerViewActions.actionOnItemAtPosition(3, click()));
```
java
1
// 点击按钮
2
onView(withId(R.id.btn_click)).perform(click());
3
 
4
// 检查文本
5
onView(withId(R.id.tv_hello))
6
.check(matches(withText("Hello Android")));
7
 
8
// 输入文本
9
onView(withId(R.id.edit_input)).perform(typeText("测试输入"));
10
 
11
// 滚动列表并点击
12
onView(withId(R.id.recycler))
13
.perform(RecyclerViewActions.actionOnItemAtPosition(3, click()));
◆

测试配置


```groovy
// build.gradle 依赖配置
androidTestImplementation 'androidx.test:runner:1.5.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
androidTestImplementation 'androidx.test.espresso:espresso-contrib:3.5.1'
testImplementation 'junit:junit:4.13.2'
testImplementation 'org.mockito:mockito-core:5.3.0'
```
groovy
1
// build.gradle 依赖配置
2
androidTestImplementation 'androidx.test:runner:1.5.2'
3
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
4
androidTestImplementation 'androidx.test.espresso:espresso-contrib:3.5.1'
5
testImplementation 'junit:junit:4.13.2'
6
testImplementation 'org.mockito:mockito-core:5.3.0'