移动开发中的测试:概念、类型及如何组织

作者: IT Sectr 发布日期: 2026-03-31 阅读时间: 9 分钟

移动应用测试是验证应用程序是否正确运行、不崩溃并满足要求的过程。根据Software Testing Help (2025)的数据,自动化测试比手动测试将回归检查时间减少70–80%。本文将介绍测试级别、iOS和Android的工具、TDD和BDD,以及CI/CD测试。

要点

  • 单元测试验证单个函数和类;集成测试验证模块交互;E2E覆盖完整的用户场景。
  • iOS:XCTest用于单元测试,XCUITest用于UI测试。Android:JUnit + Mockito + Espresso。
  • 跨平台框架:Detox(React Native)、Appium(通用)、XCUITest(iOS)。
  • TDD(测试驱动开发)——先写测试,再写代码;BDD——用简单语言描述场景。
  • CI/CD:每次推送自动运行测试——这是商业开发的强制标准。

测试级别:Unit、Integration、E2E

单元测试

单元测试是移动应用测试的基础。它们验证最小的代码单元——单个函数、方法或类,与系统其余部分隔离。在移动开发中,单元测试用JUnit(Android)和XCTest(iOS)编写。一个好的单元测试必须快速、独立且可重复——不应依赖网络、数据库或UI组件。为了隔离,使用测试替身:mock、stub和fake。

Mockito(Java/Kotlin)和MockK(Kotlin优先)是在Android上创建mock对象的热门库。在iOS上,使用OCMock、Cuckoo或手动协议。规则:单元测试应覆盖业务逻辑和数据模型。UI测试不应重复单元测试——它们验证用户与界面的交互。

集成测试

集成测试验证组件之间的交互:仓库与数据库、ViewModel与API服务、屏幕间的导航。与单元测试不同,集成测试使用真实或接近真实的依赖(例如,内存数据库或mock服务器)。Robolectric是一个无需模拟器即可在JVM上运行Android测试的框架,将集成测试加速10倍。

快照测试(Golden Tests)是一种特殊类型的集成测试,它将渲染的UI组件与参考图像(快照)进行比较。如果外观发生变化,测试就会失败——开发人员可以看到变化。Facebook SnapshotTestCase(iOS)和Shot(Android)是快照测试的流行工具。

E2E和UI测试

E2E测试(端到端)从头到尾验证完整的用户场景:启动应用、登录、执行操作、检查结果。UI测试是E2E的子集,专注于界面。工具:Espresso(Android)、XCUITest(iOS)、Detox(React Native)。E2E测试最慢,因此在CI上单独运行——通常在夜间构建中。

iOS工具:XCTest和XCUITest

XCTest

XCTest是Apple内置的移动应用单元测试框架。XCTestRunner在模拟器或真实设备上运行测试。测试继承自XCTestCase,包含用于准备和清理的setUp和tearDown。XCTest包括用于断言的XCTAssert(XCTAssertEqual、XCTAssertNil、XCTAssertTrue)和用于等待异步操作的XCTWaiter。

简单XCTest测试示例:创建User模型,验证初始化的正确性、姓名格式和年龄计算。Xcode中的代码覆盖率显示哪些代码行被测试覆盖——商业项目的目标:至少70–80%的业务逻辑覆盖率。XCTest通过xcodebuild test与Xcode Server和CI系统集成。

XCUITest

XCUITest是Apple的UI测试框架。通过辅助功能标识符工作:XCUIElementQuery根据标签、标识符或类型查找按钮、输入字段、表格。XCUITest记录操作序列(录制/回放)并生成测试代码。重要:为了测试的稳定运行,所有UI元素必须具有accessibilityIdentifier。

Android工具:JUnit、Espresso、Robolectric

JUnit和Mockito

JUnit是在Java/Kotlin上进行移动应用模块测试的基本框架。在Android上,使用JUnit 4(最新稳定版4.13.2)和新项目使用JUnit 5。Mockito是用于创建mock对象的库:when(mock.method()).thenReturn(value)——一种将被测类与依赖隔离的标准模式。

Android的JUnit测试示例:

java
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;

import static org.junit.Assert.*;
import static org.mockito.Mockito.*;

@RunWith(MockitoJUnitRunner.class)
public class LoginViewModelTest {

    @Mock
    AuthRepository authRepository;

    @Test
    public void login_emptyEmail_returnsError() {
        LoginViewModel vm = new LoginViewModel(authRepository);
        String result = vm.login("", "password123");
        assertEquals("Email cannot be empty", result);
        verify(authRepository, never()).authenticate(any());
    }
}

Espresso和UI Automator

Espresso是Google的Android UI测试框架。Espresso自动与UI线程同步:onView(withId(R.id.button)).perform(click()).check(matches(isDisplayed()))。Espresso由于内置空闲状态等待,易于编写且稳定。UI Automator是一个跨应用程序测试框架,可以与系统元素(权限对话框、通知栏)交互。

跨平台工具:Detox、Appium

用于React Native的Detox

Detox是Wix开发的React Native移动应用测试的灰盒E2E框架。Detox从单个测试代码库在两个平台上运行,内部使用Espresso(Android)和XCUITest(iOS)。Detox自动等待应用处于空闲状态(无动画、网络请求、计时器),然后才执行下一个操作。

Appium

Appium是一个通用的跨平台框架,支持Android、iOS、Web和混合应用。Appium使用WebDriver协议,支持任何编程语言(Java、Python、JS、Ruby)。Appium Server作为HTTP服务器工作,将命令转换为原生UI Automator / XCUITest命令。Appium的主要缺点是速度:测试比原生Espresso或XCUITest运行得慢。

iOS和Android测试工具比较
标准 iOS Android
单元测试 XCTest JUnit 4/5 + Mockito
UI测试 XCUITest Espresso, UI Automator
快照测试 FBSnapshotTestCase Shot, Roborazzi
手势自动化 XCUIGesture UiAutomator touch
代码覆盖率 Xcode Code Coverage Jacoco
CI集成 xcodebuild test Gradle connectedCheck

TDD和BDD:测试方法论

TDD:测试驱动开发

TDD是一种移动应用测试方法论,测试在实现代码之前编写。红绿重构循环:(1)编写一个失败的测试(红),(2)编写最少的代码使测试通过(绿),(3)在保持测试通过的同时重构代码。TDD为新功能提供100%的测试覆盖率和清晰的架构,因为测试是需求的第一个规格说明。

BDD:行为驱动开发

BDD是TDD的扩展,测试用自然语言以Given-When-Then格式编写。Given(上下文)——When(操作)——Then(预期结果)。BDD测试对团队所有成员都易于理解:开发人员、测试人员、分析人员和客户。Mock vs Stub vs Fake:Mock验证交互(方法是否被调用),Stub返回固定数据,Fake是简化的工作实现(例如,内存数据库)。在IT Sectr,我们使用TDD处理关键业务逻辑,使用BDD处理验收场景。

测试替身是在测试中替换真实依赖的对象的通用名称。有四种类型:Dummy(用于填充参数的对象,不使用)、Stub(返回给定值)、Spy(记录调用以供验证)、Mock(预先定义预期调用)。理解差异对于正确设计测试至关重要。

CI/CD和Device Farm

CI/CD中的测试自动化

CI/CD——持续集成和持续交付:在每次代码更改时自动构建和测试移动应用的做法。在移动开发中,CI/CD管道包括:代码检查、单元测试、集成测试、APK/IPA构建和UI测试。GitHub Actions和Bitrise是移动CI/CD的热门平台。测试应快速运行:单元测试1-2分钟,集成测试5-10分钟,UI测试15-30分钟。

Device Farm

Device Farm是用于测试的真实设备农场。Firebase Test Lab(Android)和Xcode Cloud(iOS)提供对数百种设备模型的云访问。Device Farm揭示了模拟器上不可见的问题:不同屏幕尺寸、旧设备上的性能、兼容性问题。在IT Sectr,我们定期使用Firebase Test Lab进行Android测试,使用Xcode Cloud进行iOS测试。

常见问题

测试覆盖率的多少百分比被认为是正常的?

对于商业项目,至少70–80%的业务逻辑覆盖率。UI代码更难覆盖——50%就足够了。重要的不是百分比,而是测试的质量:测试关键场景、边界情况和错误处理。

Mock和Stub有什么区别?

Mock验证交互——是否用特定参数调用了特定方法。Stub返回预定义的数据。Mock检查行为,Stub检查状态。

我应该为UI编写测试吗?

是的,但只针对关键场景:登录、注册、订单完成、支付。UI测试慢且脆弱——不要为每个屏幕编写测试。专注于用户的E2E场景。

什么是快照测试?

快照测试(Golden Test)将渲染的UI组件与参考图像进行比较。如果外观发生变化(字体、内边距、颜色),测试失败——开发人员检查更改是否有意。非常适合组件库。

如何加速E2E测试?

在多个设备上并行运行E2E测试,使用Cloud Device Farm,并将测试分组为独立组。优化测试:尽量减少等待,使用mock处理网络请求。

总结

  • 单元测试——测试金字塔的基础:快速、隔离、覆盖业务逻辑。
  • iOS:XCTest用于单元,XCUITest用于UI。Android:JUnit + Mockito,Espresso用于UI,Robolectric用于快速集成测试。
  • 跨平台框架:Detox(React Native)、Appium(通用)、XCUITest(iOS原生)。
  • TDD——代码前先测试,BDD——用业务语言描述场景(Given-When-Then)。
  • CI/CD——每次推送自动运行测试是现代开发的必要条件。
  • Device Farm——在云端真实设备上测试以识别硬件问题。
  • 测试金字塔:多单元、少集成、更少E2E——速度和覆盖率的最佳平衡。

我们将开发一款交钥匙移动应用程序

IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。

讨论项目