Kickstarter-iOS源码地址 >>
测试,是软件开发中非常重要的一个环节。我翻阅了 Kickstarter-iOS 中的大部分测试文件,这篇文章我来总结一下在 Kickstarter-iOS 中都测试了什么和怎样进行测试的。
单元测试
在 Kickstarter-iOS 中,单元测试的对象主要分两类:Model 和 ViewModel。
Model
在定义一个 Model 时,一般都会实现 Codable,并且要测试一下对于给定的 json 数据,是否可以解析成功。Kickstarter-iOS 也是这么做的:在每一个 Model 对应的测试文件里,利用假的 json 数据,测试是否可以解析成功。
例如 AuthorTests.swift
里:
func testJSONParsing_WithCompleteData() {
let author = Author.decodeJSONDictionary([
"id": 382491714,
"name": "Nino Teixeira",
"avatar": [
"thumb": "https://ksr-qa-ugc.imgix.net/thumb.jpg",
"small": "https://ksr-qa-ugc.imgix.net/small.jpg",
"medium": "https://ksr-qa-ugc.imgix.net/medium.jpg"
],
"urls": [
"web": [
"user": "https://staging.kickstarter.com/profile/382491714"
],
"api": [
"user": "https://api-staging.kickstarter.com/v1/users/382491714"
]
]
])
XCTAssertNil(author.error)
XCTAssertEqual(382491714, author.value?.id)
}
除此之外,根据具体的业务,还会有一些其他测试。
ViewModel
在 Kickstarter-iOS 中,每个 ViewModel 都会有对应的测试。这里主要讲一下有哪些小技巧值得学习的。
- 在
XCTestCase+AppEnvironment.swift
中, 通过扩展XCTestCase
定义了withEnvironment()
方法,用于替换某些全局变量,把替换后的Environment
push 到 stack 中作为当前的 Environment,执行完body()
后,再把刚刚 push 的 Environment 移除,这样可以保证不改变测试前后的 Environment。
func withEnvironment(_ env: Environment, body: () -> Void) {
AppEnvironment.pushEnvironment(env)
body()
AppEnvironment.popEnvironment()
}
func withEnvironment(...) # 具体看文件
- 基本上每一个 Model 都会定义一个 template 实例,用于在 ViewModel 中测试。
UI 测试
在 Kickstarter-iOS 中,UI 测试主要是对 ViewController 的测试,看看 UI 的显示是否有问题。
因为 Kickstarter 支持多语言,并且 iOS 设备有多种尺寸,所以定义了一个 combos
方法,用于组合各种语言和尺寸:
internal func combos<A, B>(_ xs: [A], _ ys: [B]) -> [(A, B)] {
return xs.flatMap { x in
return ys.map { y in
return (x, y)
}
}
}
另外还定义了一个方法,根据设备的大小和朝向最终把传入的 controller 转变成对应设备大小的 controller。
internal func traitControllers(device: Device = .phone4_7inch,
orientation: Orientation = .portrait,
child: UIViewController = UIViewController(),
additionalTraits: UITraitCollection = .init(),
handleAppearanceTransition: Bool = true)
-> (parent: UIViewController, child: UIViewController)
最后再用 FBSnapshotTestCase 生成各种尺寸语言组合的截图,具体代码如下:
func testAddNewCard() {
combos(Language.allLanguages, Device.allCases).forEach { language, device in
withEnvironment(language: language) {
let controller = AddNewCardViewController.instantiate()
let (parent, _) = traitControllers(device: device, orientation: .portrait, child: controller)
FBSnapshotVerifyView(parent.view, identifier: "lang_\(language)_device_\(device)")
}
}
}
这个测试就会生成以下截图:
总结
这篇文章主要对 Kickstarter-iOS 中测试的主要规律进行了总结。至于具体的测试,还请读者根据需求对具体代码进行分析。
完
想及时看到我的新文章的,可以关注我。同时也欢迎加入我管理的Swift开发群:536353151
。
网友评论