Swift 中使用Nimble 库进行单元测试
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
Swift 中使用Nimble 库进行单元测试的更多相关文章
- iOS开发:在Swift中调用oc库
先列举这个工程中用到的oc源码库: MBProgressHUD:半透明提示器,Loading动画等 SDWebImage:图片下载和缓存的库 MJRefresh: 下拉刷新,上拉加载 Alamofir ...
- Swift: 在Swift中桥接OC文件(自己创建的类文件、第三方库文件)
一.介绍 随着Swift的逐渐成熟,使用swift开发或者混合开发已经成为了一个趋势,本身苹果公司也十分推荐使用Swift这门新语言.目前Swift已经更新到了3.0,估计没有多久4.0就要出来了.那 ...
- Swift中的Masonry第三方库——SnapKit
在OC开发时我常用一个名叫Masonry的第三方Autolayout库,在转Swift后发现虽然Swift可以混编OC,但总感觉有些麻烦,在Github上发现了这个叫做SnapKit的第三方库,发现使 ...
- swift中第三方网络请求库Alamofire的安装与使用
swift中第三方网络请求库Alamofire的安装与使用 Alamofire是swift中一个比较流行的网络请求库:https://github.com/Alamofire/Alamofire.下面 ...
- swift 中使用OC第三方库(以AFNetworking为例)
首先呢 把你需要的第三方库导入到你的项目中来 具体怎么导入 这不是这篇的重点 看上一篇 废话不多 直接上 (1)在项目中直接建一个 oc 的控制器 然后xcode会提醒你 要不要建造桥接文 ...
- 怎样在swift中使用cocoapods导入的第三方oc库
假如你来到这里,说明你已经開始着手使用swift这门新语言了. 就像Java有Maven一样.Objective-C也有自己的依赖管理工具cocoapods. 可是因为swift才出来不久,眼下非常多 ...
- Swift中如何化简标准库中冗长的类实例初始化代码
可能有些童鞋并不知道,在Swift中缩写点符号对于任何类型的任何static成员都有效. 我们实际写一个例子看一下: import UIKit class CFoo{ static let share ...
- 阿里巴巴最新开源项目 - [HandyJSON] 在Swift中优雅地处理JSON
项目名称:HandyJSON 项目地址:https://github.com/alibaba/handyjson 背景 JSON是移动端开发常用的应用层数据交换协议.最常见的场景便是,客户端向服务端发 ...
- 【iOS】在Swift中使用JSONModel
前言 首先所有的Model还是使用oc来写——看到这一句是不是想关网页了- - #,在swift里面直接写一直报错所以就将就用oc来写了,这里主要是分享一下搭配Alamofire使用的经验. 声明 欢 ...
随机推荐
- (转)各种排序算法的分析及java实现
转自:http://www.cnblogs.com/liuling/p/2013-7-24-01.html 排序一直以来都是让我很头疼的事,以前上<数据结构>打酱油去了,整个学期下来才勉强 ...
- 再看.net本质(二)
3.[HTTP协议] 当浏览器寻找到Web服务器的地址之后,浏览器将帮助我们把对服务器的请求转换为一系列参数发送给Web服务器.服务器收到浏览器的请求对数之后,将会分析这些数据并进行处理,然后向浏览 ...
- HTTP协议概述
虽然cURL支持多种协议,但日常我们最常用的还是HTTP协议,下文中着重介绍HTTP的相关使用方法,因此我们要对HTTP协议有所了解. HTTP,超文本传送协议,通过因特网传送万维网文档的数据传送协议 ...
- Jquery在线引用地址:
转自:http://www.cnblogs.com/lkf18/archive/2012/12/11/2813241.html 1. 很多网站都是使用这种方式引入,客户的浏览器可能已经缓存过了 jqu ...
- Android OptionMenu
1.Java package com.fish.helloworld; import android.app.Activity; import android.content.Context; imp ...
- app开发版面设计原则
(1) 单纯:形象和色彩必须简单明了(也就是简洁性). (2) 统一:造型与色彩必须和谐,要具有统一的协调效果. (3) 均衡:整个画面须要具有魄力感与均衡效果. (4) 展现重点:构成要素必须化繁为 ...
- PO、BO、VO、DTO、POJO、DAO的区别
PO: 基本上就是Entity了 persistant object持久对象 最形象的理解就是一个PO就是数据库中的一条记录. 好处是可以把一条记录作为一个对象处理,可以方便的转为其它对象. ---- ...
- [原]hdu2045 不容易系列三——LELE的RPG难题 (递推方程)
本文出自:blog.csdn.net/svitter 原题:http://acm.hdu.edu.cn/showproblem.php?pid=2045 题意:中文不用我说了吧. 这个题目的关键就在于 ...
- MySQL 5.7.9 免安装配置
MySQL 5.7.9 免安装配置 环境:win10 64位 mysql版本:mysql-5.7.9-winx64.zip (http://dev.mysql.com/downloads/mysql/ ...
- 例题6-10 The Falling Leaves,UVA699
这道题我的思路是先通过递归构建树,然后进行遍历将位置和保存在map映射中,最后按顺序输出map集合中的值. 至于如何遍历,我是依次尝试了宽度优先遍历和深度优先遍历,当然这都是可以的.不过期间写错了很多 ...