大家好,我是程序员柏风,AI 最全的 Vibecoding 学习地图 http://coderoadmap.cn 作者。
测试与调试
iOS 测试栈:XCTest 单元/UI 测试、Instruments 性能分析、SwiftLint 代码规范。对照 /roadmaps/ios「Testing & Debugging」节点。
学习目标
- 编写 XCTest 单元测试与 Mock 依赖
- 了解 XCUITest 基础与 UI 测试局限
- 用 Instruments 定位内存泄漏与 CPU 热点
- 对照 JUnit 与 React Testing Library
核心概念
XCTest 单元测试
import XCTest
@testable import CodeRoadMap
final class TrackListViewModelTests: XCTestCase {
var sut: TrackListViewModel!
var mockRepo: MockTrackRepository!
override func setUp() {
super.setUp()
mockRepo = MockTrackRepository()
sut = TrackListViewModel(repository: mockRepo)
}
override func tearDown() {
sut = nil
mockRepo = nil
super.tearDown()
}
func testLoadTracksSuccess() async {
mockRepo.stubbedTracks = [
Track(id: 1, title: "iOS", lessonCount: 12),
]
await sut.loadTracks()
XCTAssertEqual(sut.tracks.count, 1)
XCTAssertNil(sut.errorMessage)
XCTAssertFalse(sut.isLoading)
}
func testLoadTracksFailure() async {
mockRepo.shouldFail = true
await sut.loadTracks()
XCTAssertTrue(sut.tracks.isEmpty)
XCTAssertNotNil(sut.errorMessage)
}
}
final class MockTrackRepository: TrackRepositoryProtocol {
var stubbedTracks: [Track] = []
var shouldFail = false
func fetchAll() async throws -> [Track] {
if shouldFail { throw URLError(.notConnectedToInternet) }
return stubbedTracks
}
}
@testable import 访问 internal 符号;Mock 实现 Protocol,类似 Spring @MockBean。
UI 测试(XCUITest)
func testLessonListNavigation() {
let app = XCUIApplication()
app.launch()
XCTAssertTrue(app.navigationBars["课时"].exists)
app.tables.cells.firstMatch.tap()
XCTAssertTrue(app.staticTexts["详情"].waitForExistence(timeout: 2))
}
UI 测试慢且脆弱,覆盖关键用户路径即可;大部分逻辑应在单元测试验证。
调试工具
| 工具 | 用途 |
|---|---|
| LLDB 断点 | 运行时检查变量 |
| View Hierarchy | 查看 UI 层级与约束 |
| Instruments → Leaks | 内存泄漏 |
| Instruments → Time Profiler | CPU 热点 |
| SwiftLint | 代码风格与常见错误 |
# SwiftLint(Homebrew 安装)
swiftlint lint --strict
与 Java/Spring 或 React 对照
| iOS | Java / Spring | React |
|---|---|---|
| XCTest | JUnit 5 | Vitest / Jest |
| XCUITest | Selenium / Playwright | Playwright / Cypress |
@testable import | package-private 测试 | — |
| Mock Protocol | @MockBean Mockito | vi.fn() mock |
| Instruments | JProfiler / VisualVM | React Profiler |
Spring Boot 测试见 @SpringBootTest;iOS ViewModel 纯 Swift 逻辑无需启动 Simulator,测试更快。
练习
- 为
TrackListViewModel写成功/失败两个单元测试 - 添加 SwiftLint 到 Build Phase,修复一条 warning
- 用 Instruments Leaks 检查一个已知循环引用
小结
XCTest + Mock Protocol 是单元测试核心;Instruments 查性能。 下一课上架发布。见 ios-essentials。