您的位置:首页 > 移动开发 > Swift

iOS Swift教程 Core Data (六)单元测试

2015-01-07 09:18 387 查看
单元测试是一种用于将软件按较小的单元进行测试的方法。不同于测试”点击按钮来创建一个新的记录“,单元测试会将这个测试拆分为测试按钮按下事件、创建entity、测试是否保存成功等等。

为什么我们需要关心app的单元测试呢?有以下几个原因:

单元测试用于在项目的初期验证你的架构和程序的行为。你可以测试app的很多功能而不需要关心UI的设计和实现。
单元测试让你有信心为app添加新的功能或进行重构,而不用担心破坏app已有的其它功能。如果现有的测试用例都能够pass,在添加新功能后,如果有测试用例fail了,则代表你破坏了已有的功能。
当多个开发人员同时进行一个项目的开发时,单元测试使得各个开发人员可以独立并行的进行开发。
如果当你要测试某个功能,需要多次点击不同的界面然后输入一些数据才能测试某个feature时,单元测试可以使你对你的app的任意部分进行独立的测试,比起通过UI操作来进行测试,要便利很多。

在这一节中,你将学到如何使用Xcode中的XCTest框架来测试你的Core Data应用程序。

开始

这一节的示例工程名为CampgroundManager,是一个用于对露营地、每个露营地的特色以及露营者进行管理的一个预约系统。一个小的露营地可以使用这个程序来管理它的各个露营点,预约情况包括时间和付款信息。用户界面很简单,但是对于演示作用已经足够了。

这里我们会将整个程序分拆为几个小的模块,然后开发单元测试并实现这些模块。小模块按主题被分为三类:露营地、露营者和预约,单元测试将主要关注这三类服务。

由于我们要测试应用程序的Core Data,首先得为测试建立Core Data Stack。

为测试构建Core Data Stack

好的单元测试应该符合FIRST原则:

Fast:执行速度快
Isolated:各个测试用例应该可以独立运行
Repeatable:对于相同的case,执行多次应该得到相同的结果
Self-verifying:测试用例应该可以自动报告成功或失败而不需要人为的检查输出或者日志文件
Timely:即时,完成一个小的新功能后,立即执行测试用例,以检验功能是否正确

CampgroundManager使用Core Data来存储数据到数据库中。这就不是很独立,因为一个测试用例对数据库的操作可能会影响另一个测试用例。也不没有很高的可重复执行性,因为需要为每个测试都去构造数据库文件。当然,你可以在每个case执行前删除老得数据库构造一个新的,但是这就会降低测试用例执行的速度。

解决办法是修改Core Data栈,使用in-memory store而不是基于SQLite后台的存储器。这就可以保证每次case执行前都是干净的,并且,执行效率也很高。

这里我们创建一个Core Data stack的子类,在CampgroundManagerTest目录下创建一个新的swift文件TestCoreDataStack.swift(不需要Objective-C bridging header)并添加以下代码:

import Foundation
import CampgroundManager
import CoreData

class TestCoreDataStack: CoreDataStack {
override func initPSC() {
var psc: NSPersistentStoreCoordinator? = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel)
var error: NSError? = nil

var ps = psc!.addPersistentStoreWithType(NSInMemoryStoreType, configuration: nil, URL: nil, options: nil, error: &error)

if ps == nil {
abort()
}

persistentStoreCoordinator = psc
}
}


第一个测试用例

单元测试需要你在脑海中将自己的app设计为一些小的模块。我们创建一个类来封装这些逻辑而不是将所有的逻辑写到一个巨大的view controller中。

大多数情况下,你可能会为你已经完成了一部分功能的程序添加单元测试。比如CampgroundManager,已经创建好了CamperService、CampSiteService和ReservationService类,但是并没有完全实现整个feature。接下来我们对最简单的类进行测试-CamperService。

创建一个新的测试类,CamperServiceTests。右键选择CampGroundManagerTests目录下得Services子目录,选择new file,选择Test Case Class命名为CamperServiceTests。在其中添加以下代码:在setUp函数中初始化测试环境,在tearDown函数中释放资源。测试用例testAddCamper用于测试camperService的addCamper接口,这个接口接收2个参数,camper的名字和电话号码。然后检查新添加的camper是否为空,他的名字和电话是否正确。

import CampgroundManager
import CoreData

class CamperServiceTests: XCTestCase {

var camperService: CamperService!
var coreDataStack: CoreDataStack!

override func setUp() {
super.setUp()

// Put setup code here. This method is called before the invocation of each test method in the class.
coreDataStack = TestCoreDataStack()
camperService = CamperService(managedObjectContext: coreDataStack.mainContext!, coreDataStack: coreDataStack)
}

override func tearDown() {
// Put teardown code here. This method is called after the invocation of each test method in the class.
super.tearDown()

camperService = nil
coreDataStack = nil
}

func testAddCamper() {
let camper = camperService.addCamper("Bacon Lover", phoneNumber: "13888888888")

XCTAssertNotNil(camper, "Camper should not be nil")
XCTAssertTrue(camper?.fullName == "Bacon Lover")
XCTAssertTrue(camper?.phoneNumber == "13888888888")
}
}
点击Product菜单,选择Test(Command+U)来执行测试用例,你将看到如下效果:



以及如下的命令行输出:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: