Swift 中使用Nimble 库进行单元测试
2015-06-30 10:50
99 查看
Nimble 从字面上看是
我们看到了 Xcode 为我们自动生成的
让我们看看测试项目中的代码,
这是测试项目中唯一的一个类,它继承自
我们在断言中判断变量 i 应该等于0,但我们实际给 i 赋值为 1。这时候我们再按 Command + U 来运行测试,这次我们的测试没有通过,因为断言失败了:
我们看到,
既然
下面我们来看看如何用
首先我们将
然后我们把 Nimble-iOS 作为测试 Target 的依赖库添加进来:
然后我们再修改
我们看到,我们将断言方式改为
我们继续主题,按下 Command + U 运行单元测试,断言依然会失败:
而这次给出的错误消息,是
好了,我们现在可以修正一下代码,让断言通过了:
我们现在对
对于 Swift, Nimble 也提供了操作符重载的支持,比如我们上面判断相等的方法,也可以写成这样:
类似的,我们还可以进行比较操作:
我们看到,每一个比较方法,在 Swift 中都提供了操作符重载,非常方便。
我们还可以对异步方法进行测试:
还可以使用
你还可以用 Nimble 来判断两个实例的引用是否相同:
Nimble,还提供了一系列方法供我们使用,更加详细的内容大家可以残开 Nimble 的 Github 主页: https://github.com/Quick/Nimble
敏捷,灵活的意思。Nimble 是一个库,一个
断言库。这个库一般用于单元测试。Xcode 6 为我们集成了
XCTest单元测试库。在正式介绍 Nimble 之前,我们有必要先介绍一下
XCTest。我们在使用 Xcode 新建项目的时候会发现它为我们创建了两个
Target,一个是我们项目的
Target还有一个就是测试
Target。
我们看到了 Xcode 为我们自动生成的
Target,我们按下 Command + U 即可运行测试项目,并且在 Xcode 的左边会显示测试结果:
让我们看看测试项目中的代码,
MyTestTests.swift:
import UIKit import XCTest class MyTestTests: XCTestCase { override func setUp() { super.setUp() // Put setup code here. This method is called before the invocation of each test method in the class. } override func tearDown() { // Put teardown code here. This method is called after the invocation of each test method in the class. super.tearDown() } func testExample() { // This is an example of a functional test case. XCTAssert(true, "Pass") } func testPerformanceExample() { // This is an example of a performance test case. self.measureBlock() { // Put the code you want to measure the time of here. } } }
这是测试项目中唯一的一个类,它继承自
XCTestCase,并且里面实现了四个方法。其中以 test 开头的两个方法
testExample和
testPerformanceExample是具体的测试用例方法。我们看到
testExample方法里面调用了一个
XCTAssert(true, "Pass")方法。这个方法叫做断言方法,也是单元测试的核心。对于
XCAssert方法,只有第一个参数为
true的时候,测试用例才会通过。比如我们把这个方法改成这样:
func testExample() { // This is an example of a functional test case. var i = 1; XCTAssert(i == 0, "variable i shoule be zero.") }
我们在断言中判断变量 i 应该等于0,但我们实际给 i 赋值为 1。这时候我们再按 Command + U 来运行测试,这次我们的测试没有通过,因为断言失败了:
我们看到,
Xcode将
XCAssert的第二个参数用作错误提示显示了出来。这个例子说明了断言在单元测试中的作用。
既然
XCTest已经提供了像
XCAssert这样的断言方法,我们为什么还需要用
Nimble呢? 简单来说,
XCTest虽然提供了一系列的断言方法,但并不全面,比如它无法判断字符串包含关系,集合对象是否包含一个子集,以及测试异步方法的返回值。
Nimble解决了这个问题,它弥补了
XCTest的上述缺陷。并且还更加和 BDD(一种叫做行为驱动开发的测试模式) 贴合。
下面我们来看看如何用
Nimble来表达上面的断言逻辑。
首先我们将
Nimble库添加到项目中,并将
.xcodeproj文件放到项目结构中:
然后我们把 Nimble-iOS 作为测试 Target 的依赖库添加进来:
然后我们再修改
testExample方法:
func testExample() { var i = 1; expect(i).to(equal(0)) }
我们看到,我们将断言方式改为
expect(i).to(equal(0))。顺便说句题外话~,这样感觉是不是更加符合自然语言的逻辑,更贴近人性呢?
XCTAssert(i == 0, "variable i shoule be zero.")给人的感觉只是一个函数调用,而
expect(i).to(equal(0))就仿佛是在说一句话一样,翻译成中文就是:“期望变量 i 等于 0 ”。
我们继续主题,按下 Command + U 运行单元测试,断言依然会失败:
而这次给出的错误消息,是
Nimble自动生成的(其实绝大多数情况下,自动生成的错误消息就足够用了)。
好了,我们现在可以修正一下代码,让断言通过了:
我们现在对
Nimble有了一个初步的认识了。而
Nimble能为我们提供的,远不止这些。下面我们来继续了解。
对于 Swift, Nimble 也提供了操作符重载的支持,比如我们上面判断相等的方法,也可以写成这样:
expect(i) == 0
类似的,我们还可以进行比较操作:
expect(i).to(equal(0)) expect(i) == 0 expect(i).to(beGreaterThan(-2)) expect(i) > -2 expect(i).to(beGreaterThanOrEqualTo(0)) expect(i) >= 0 expect(i).to(beLessThan(2)) expect(i) < 2 expect(i).to(beLessThanOrEqualTo(1)) expect(i) <= 1
我们看到,每一个比较方法,在 Swift 中都提供了操作符重载,非常方便。
我们还可以对异步方法进行测试:
var collection:Array<String> = [] dispatch_async(dispatch_get_main_queue()) { collection.append("first") collection.append("second") } expect(collection).toEventually(contain("first","second"))
还可以使用
waitUntil方法来阻塞当前线程,直到某些操作执行完成:
waitUntil { done in NSThread.sleepForTimeInterval(0.5) done() }
你还可以用 Nimble 来判断两个实例的引用是否相同:
expect(actual).to(beIdenticalTo(expected)) expect(actual) === expected
Nimble,还提供了一系列方法供我们使用,更加详细的内容大家可以残开 Nimble 的 Github 主页: https://github.com/Quick/Nimble