每个 iOS 程序员都要时不时的为他们的 app 做 debug。除非你是那种超级大牛,否则你肯定体验过查了无数个小时的 bug 最后才发现那仅仅是个简单的语法错误时那种油然而生的绝望感。或者更糟:你根本就没发现那些 bug。无论你是编程新手,还是开发过很多 app 的老司机,例行的写写单元测试会让你的代码更可靠,更安全,更容易 debug! 你很走运,Xcode 7 和 Swift 支持单元测试。尽管单元测试不保证(有了它你就会写出)绝对没有 bug 的 app,它还是一种能让你验证每段代码是否如期工作,并让 debug 过程更加便利。 正如其名,在单元测试中你要为某段代码单元创建一些小规模的、针对其某个特性的测试,然后确保每个代码单元都能通过这些测试。如果通过的话,它的旁边会出现一个绿色小标志,而如果因故测试不通过, Xcode 会把该测试标记为 “failed”。这就提示你去查看代码,找出失败原因。 演示项目概览首先下载这个我为你准备的 starting project 。一个短小精悍的 app:它会对一个给定的数字和百分比做一个乘法计算。(比如80的10%是8。) 这个 PercentageCalculator 项目非常简单。你唯一需要关注的就是 ViewController.swift 这个文件。里面的代码都标记了注释,很容易理解。 有 5 个 IBOutlets:每一个都对应了屏幕上一个 UIElement,除 title(标题)之外,还有 2 个 slider 对应 2 个 IBActions。每个 IBAction 的方法名都精确描述了其用途及将要执行的操作。当一个 slider 值改变时,其对应着的百分比或数字的值也会随之改变。 还有两个简单的函数 “updateLabels()” 和 “percentage()” 做了符合期待的事情:当一个 slider 改变时第一个函数更新 label,第二个函数获取两个浮点数并返回百分比的计算结果。 在模拟器中运行 app。刚开始一切看起来都很正常。但当你开始改变数字时就会发现计算结果有问题。为找到 bug,我们将代码分割成不同的单元,然后分别做测试,看看每个是否都如期运行。这不会解决 bug,但能缩小你的查找范围。 我创建项目的时候,默认情况下会勾选创建一个 test 文件的选项(如果你想要手动加一个的话,在 iOS Source 下面选择 select File > New > File > Unit Test Case Class)。我们的例子中 test 文件已经被 Xcode 自动创建出来,可以在项目导航栏中 “PercentageCalculatorTests” 文件夹中找到它。 在 开始写单元测试吧现在是时候写你的第一个单元测试函数了!本教程我们只测试 class PercentageCalculatorTests: XCTestCase { var vc: ViewController! override func setUp() { super.setUp() // 这里写setup的代码。本class里每个测试函数被调用之前该方法都会被先调用。 } override func tearDown() { // 这里写teardown的代码。本class里每个测试函数被调用之后该方法都会被调用。 super.tearDown() } }
在 setup 方法中实例化一个 override func setUp() { super.setUp() let storyboard = UIStoryboard(name: "Main", bundle: NSBundle.mainBundle()) vc = storyboard.instantiateInitialViewController() as! ViewController } 现在你应该记得所有的测试方法的名字都要以 func testPercentageCalculator() { } 单元测试中你要去检查某段代码是否如你所愿的那样工作。待测试的代码段一般都只有几行,典型情况是你只需要测试一个方法或者一个函数。单元测试是这样去做的:你给某个代码单元一个输入值,让这个值过一遍这段代码,然后检查一下输出的值是否和预期的一样。 与“我们期望的那个值”做比较的这部分由 尝试一下!首先给 func testPercentageCalculator() {
XCTAssert(true)
}
如果一切顺利,则测试通过,方法左边会出现一个绿色检测标。 验证百分比计算现在来真的:测试 func testPercentageCalculator() {
// 应该是25
let p = vc.percentage(50, 50)
XCTAssert(p == 25)
}
测试成功了,这意味着 验证Labels现在添加一个新的测试方法 注意到你要给 func testLabelValuesShowedProperly() {
vc.updateLabels(Float(80.0), Float(50.0), Float(40.0))
// labels应该显示80, 50 and 40
XCTAssert(vc.numberLabel.text == "80.0", "numberLabel doesn't show the right text")
XCTAssert(vc.percentageLabel.text == "50.0%", "percentageLabel doesn't show the right text")
XCTAssert(vc.resultLabel.text == "40.0", "resultLabel doesn't show the right text")
}
你尝试执行这个测试方法时,会收到编译器的错误提示: 我是在 storyboard 文件中创建了这些 labels 的,因此只有当 view 被加载之后(loaded)它们才会被初始化,然而由于对单元测试来说 正确的方法是你应该先访问一下 func testLabelValuesShowedProperly() {
let _ = vc.view
vc.updateLabels(Float(80.0), Float(50.0), Float(40.0))
// labels应该显示80, 50 and 40
XCTAssert(vc.numberLabel.text == "80.0", "numberLabel doesn't show the right text")
XCTAssert(vc.percentageLabel.text == "50.0%", "percentageLabel doesn't show the right text")
XCTAssert(vc.resultLabel.text == "40.0", "resultLabel doesn't show the right text")
}
注意到下划线(_)忽略了常量的名字。因为我们实际上并不需要用到这个 view。加下划线就是告诉编译器“你假装访问一下这个 view,把相应的方法触发就行。” 执行测试。(如果想一并执行我们test类的所有测试,你还可以点击 “class PercentageCalculatorTests” 旁边的那个方块)。 ###我们来修Bug 如你所见,测试失败了!我们给 XCTAssert 方法传入的错误细节消息帮助我们快速识别出引起 bug 的可能原因。这次测试告诉我们 resultsLabel 没有显示出正确的文本,所以我们进到 ViewController 里看看对这些 label 的 text 值是在那里被设置的。仔细看了 self.resultLabel.text = "\(rV + 10)" 应该是: self.resultLabel.text = "\(rV)" 更新代码之后再运行一次测试,一切都应该正常了! 结论本篇教程中你学到了 Xcode 中的单元测试的相关内容,以及它怎样能够帮你找到代码中的 bug。除了预防 bug 之外,单元测试还可以用来做性能测试和异步测试。还可能让你感兴趣的是UI测试,你可以录制下你在 app 上做出的动作来测试你的 app 在实际使用情景下是如何表现的。如果听起来觉得感兴趣,那一定要看看这个讲 UI 测试的WWDC视频 。 项目的最终版本可以在 Github上下载 。 如果你有关于 UI 测试的任何问题,或者学习本教程中遇到了困难,请在评论中点我! 作者介绍:Maxime Defauw 是一个有经验的程序员,在 App Store 和 Google Play store 上发布过多个 app。他今年 16 岁,居住在比利时。最近他在 San Francisco 举行的 WWDC15 上获得了 Apple 的奖学金。Max 熟练掌握 Objective-C,C,C#,现在是 Swift。不码代码的时候他一般在曲棍球场或者高尔夫球场上。在 Twitter 上@MaximeDefauw 粉他。 |
|
声明:文章版权归原作者所有 部分文章转自互联网 如有侵权请联系
[邮箱地址] 删除
|