Swift — 4 —核心数据—第4部分编写单元测试用例

嗨,我回来了,我最喜欢的主题核心数据带有单元测试😀。 希望您对编写单元测试用例有一些基本的了解。 我们将使用XCTestCase类XCTest框架来编写单元测试并对其进行测试。 源代码在本教程的底部。

单元测试对于测试代码非常有用,而无需在设备或模拟器上启动代码并转到特定的视图控制器。 我们可以非常快速地测试所需的代码,而无需在设备/模拟器上运行。 它将节省大量的开发时间。

一旦您采用了单元测试,它将激发您按照MVVM,依赖注入和适配器模式等编写小的可测试代码。

我将继续第3部分。请从此处下载第3部分源代码。

我在CoreDataManager类中添加了另一个方法。 只需复制以下方法并粘贴到CoreDataManager类中即可。 此方法使用获取请求来获取个人记录并删除它们。

  / *在需要刷新人员数据的情况下,可以调用此方法* / 
func flushData(){

让fetchRequest:NSFetchRequest = NSFetchRequest (实体名称:“人”)
让objs =试试! CoreDataManager.sharedManager.persistentContainer.viewContext.fetch(fetchRequest)
例如,让obj作为objs中的NSManagedObject {
CoreDataManager.sharedManager.persistentContainer.viewContext.delete(obj)
}

尝试! CoreDataManager.sharedManager.persistentContainer.viewContext.save()
}
}

现在,让我们开始设置单元测试:

我们还需要在测试目标中添加PersonData.xcdatamodeld。 请参考所附的屏幕截图,并仔细查看右侧底部的Target Membership:

让我们复制下面的代码,并将其粘贴到PersonDataTests.swift中。 它看起来应该像这样:

  // 
// PersonDataTests.swift
// PersonDataTests
//
//由Alok Upadhyay在18/3/28创建。
//版权所有©2018 Alok。 版权所有。
//
 导入XCTest 
导入CoreData
@testable导入PersonData
  class PersonDataTests:XCTestCase { 

/ *创建一个CoreDataManager对象,我们将使用该对象来测试诸如插入,更新和删除之类的操作* /
var coreDataManager:CoreDataManager!

覆盖func setUp(){
super.setUp()
//在此处放置设置代码。 在调用类中的每个测试方法之前,将调用此方法。
coreDataManager = CoreDataManager.sharedManager
     } 

覆盖func tearDown(){
//在此处放置拆卸代码。 调用类中的每个测试方法后,将调用此方法。
super.tearDown()
}

func testPerformanceExample(){
//这是一个性能测试用例的示例。
自我衡量{
//在此处放置您要测量时间的代码。
}
}

// MARK:我们的测试用例

/ *此测试案例测试了CoreDataManager类的正确初始化:)* /
func test_init_coreDataManager(){

让实例= CoreDataManager.sharedManager
/ *声明表达式不是nil。
当expression == nil。* /时生成失败
XCTAssertNotNil(实例)
}

/ *测试NSPersistentContainer(实际的核心数据堆栈)是否成功初始化
* /
func test_coreDataStackInitialization(){
让coreDataStack = CoreDataManager.sharedManager.persistentContainer

/ *声明表达式不是nil。
当expression == nil。* /时生成失败
XCTAssertNotNil(coreDataStack)
}

/ *此测试用例插入一个人的记录* /
func test_create_person(){

//给出名字和ssn
让name1 =“ Alok”
令ssn1 = 123

let name2 =“ Naitvik”
让ssn2 = 456

让name3 =“ Deepti”
令ssn3 = 789

让person1 = coreDataManager.insertPerson(name:name1,ssn:Int16(ssn1))

/ *声明表达式不是nil。
当expression == nil。* /时生成失败
XCTAssertNotNil(person1)

让person2 = coreDataManager.insertPerson(name:name2,ssn:Int16(ssn2))

/ *声明表达式不是nil。
当expression == nil。* /时生成失败
XCTAssertNotNil(person2)

让person3 = coreDataManager.insertPerson(name:name3,ssn:Int16(ssn3))

/ *声明表达式不是nil。
当expression == nil。* /时生成失败
XCTAssertNotNil(person3)

}

/ *此测试用例获取所有人记录* /
func test_fetch_all_person(){

//获取personRecord已保存

让结果= coreDataManager.fetchAllPersons()

//声明待办事项的返回编号
//声明两个可选值相等。
XCTAssertEqual(results.count,3)
}

func test_remove_person(){

/ *获取所有项目* /
让项目= coreDataManager.fetchAllPersons()
/ *获取第一项* /
让人=物品![0]

/ *项目总数* /
让numberOfItems = items?.count

//删除一个项目
coreDataManager.delete(person:person)

//声明项目编号-1.删除项目后,sut.fetchAllPersons()?. count应该等于numberOfItems!-1。
XCTAssertEqual(coreDataManager.fetchAllPersons()?. count,numberOfItems!-1)
}

func test_remove_person_ssn(){

/ *获取所有项目* /
让项目= coreDataManager.fetchAllPersons()

/ *项目总数* /
让numberOfItems = items?.count

//删除一个项目
coreDataManager.delete(ssn:“ 789”)

//声明项目编号-1.删除项目后,sut.fetchAllPersons()?. count应该等于numberOfItems!-1。
XCTAssertEqual(coreDataManager.fetchAllPersons()?. count,numberOfItems!-1)
}

func test_update_person(){

/ *获取所有项目* /
让项目= coreDataManager.fetchAllPersons()
/ *获取第一项* /
让个人=物品![0]
让名字=“约翰”
令ssn = 999

CoreDataManager.sharedManager.update(名称:名称,ssn:Int16(ssn),人:人)

/ *获取所有项目* /
让itemsFetched = coreDataManager.fetchAllPersons()
/ *获取第一项* /
让personFetched =物品![0]
XCTAssertEqual(name,personFetched.name)
XCTAssertEqual(ssn,Int(personFetched.ssn))

}

/ *测试是否从存储中删除了所有数据* /
func test_flushData(){
coreDataManager.flushData()

/ *如果fetchAllPerson返回0个对象,则此测试用例通过* / XCTAssertEqual(coreDataManager.fetchAllPersons()?. count,0)
}

}

让我们突破上面的代码并理解它:

注意:每种测试方法都必须以测试词开头。

导入XCTest

我们将使用此框架进行单元测试。

导入CoreData

我们将使用CoreData框架来访问特定于核心数据的类。

@testable导入PersonData

我们将测试PersonData目标。

PersonDataTests:XCTestCase

我们将不得不 继承XCTestCase 来编写单元测试用例。

var coreDataManager:CoreDataManager! 创建一个CoreDataManager对象,我们将使用该对象来测试插入,更新和删除等操作。

  覆盖 func setUp (){ 
super .setUp()//将安装代码放在这里。 //调用类中的每个测试方法之前,将调用此方法。
coreDataManager = CoreDataManager.sharedManager
}

这是一种生命周期方法,每次您运行测试用例时都会首先调用它。 我们正在用此方法初始化coreDataManager对象。

  覆盖 func tearDown (){//将拆卸代码放在此处。  //调用类中的每个测试方法后,将调用此方法。 
超级 .tearDown()
}

这是一个生命周期方法,每次您运行测试用例后都会调用它。

  func test_init_coreDataManager(){ 
let instance = CoreDataManager.sharedManager / *断言表达式不是nil。 当expression == nil。* / XCTAssertNotNil(instance)时生成失败
}

此测试用例测试了CoreDataManager类的正确初始化:)。 如果没有实例,它将失败。 如果通过,则表示CoreDataManager.sharedManager返回有效实例。

让我们进行测试并直观地看到它:

让我们测试一下test_coreDataStackInitialization

  func test_coreDataStackInitialization (){ 
coreDataStack = CoreDataManager.sharedManager.persistentContainer / *断言表达式不是nil。 当expression == nil。* /时生成失败
XCTAssertNotNil(coreDataStack)
}

此测试用例测试了NSPersistentContainer(实际核心数据堆栈)是否成功初始化。 万一无法获得适当的实例,它将生成一个失败。 如果通过,则表示我们正在获取有效的persistentContainer。

让我们进行测试并直观地看到它:

让我们测试一下test_create_person

  func test_create_person(){ 

//给出名字和ssn
name1 =“ Alok”
ssn1 = 123

let name2 =“ Naitvik”
ssn2 = 456

name3 =“ Deepti”
ssn3 = 789

person1 = coreDataManager.insertPerson(name:name1,ssn:Int16(ssn1))

/ *声明表达式不是nil。
当expression == nil。* /时生成失败
XCTAssertNotNil(person1)

person2 = coreDataManager.insertPerson(name:name2,ssn:Int16(ssn2))

/ *声明表达式不是nil。
当expression == nil。* /时生成失败
XCTAssertNotNil(person2)

person3 = coreDataManager.insertPerson(name:name3,ssn:Int16(ssn3))

/ *声明表达式不是nil。
当expression == nil。* /时生成失败
XCTAssertNotNil(person3)

}

在此测试用例中,我们正在插入人员记录。 当expression == nil时生成失败。 如果通过,则表示coreDataManager.insertPerson返回有效的人员对象。 如果插入成功,则必须将其取回。 让我们尝试获取个人记录。 由于我们已经在核心数据中保存了三个人记录,因此我们应该获取它们。 我们正在使用XCTAssertEqual。

让我们进行测试并直观地看到它:

让我们测试CoreDataManager类的fetchAll方法。

  func test_fetch_all_person (){ 

//获取personRecord已保存

结果= coreDataManager.fetchAllPersons()

//声明待办事项的返回编号
//声明两个可选值相等。
XCTAssertEqual(results.count,3)
}

让我们进行测试并直观地看到它:

让我们深入到test_remove_person。

  func test_remove_person(){ 

/ *获取所有项目* /
项目= coreDataManager.fetchAllPersons()
/ *获取第一项* /
个人=物品![0]

/ *项目总数* /
numberOfItems = items?.count

//删除一个项目
coreDataManager。 删除 (人:人)

//声明项目编号 -1.删除项目后,sut.fetchAllPersons()?. count应该等于numberOfItems!-1。
XCTAssertEqual(coreDataManager.fetchAllPersons()?. count,numberOfItems!-1)
}

在这个测试案例中,我们正在获取所有人员并从返回的项目中删除第一个对象。 在XCTAssertEqual中,我们正在测试是否相等。

让我们进行测试并直观地看到它:

让我们测试一下test_remove_person_ssn

  func test_remove_person_ssn(){ 

/ *获取所有项目* /
项目= coreDataManager.fetchAllPersons()

/ *项目总数* /
numberOfItems = items?.count

//删除一个项目
coreDataManager。 删除 (ssn:“ 789”)

//声明项目编号 -1.删除项目后,sut.fetchAllPersons()?. count应该等于numberOfItems!-1。
XCTAssertEqual(coreDataManager.fetchAllPersons()?. count,numberOfItems!-1)
}

我们的应用程序具有可以通过其sn删除某人的功能。 首先,我们要获取所有人的记录。 然后我们调用delete(ssn:“ 789”)。 这将删除ssn号为“ 789”的人。 在XCTAssertEqual中,我们正在测试是否相等。

让我们进行测试并直观地看到它:

我希望现在您应该能够测试最后的单元测试用例刷新数据

  func test_flushData(){ 
coreDataManager.flushData()

/ *如果fetchAllPerson返回0个对象,则此测试用例通过* / XCTAssertEqual(coreDataManager.fetchAllPersons()?. count,0)
}

只需按照我上面讨论的方式进行测试即可。 XCTAssertEqual相等性检查总计数是否为零。 调用coreDataManager的flushData之后 ,应从核心数据中删除Person实体。 也就是说,提取将给我们0个结果。

希望你喜欢阅读。 请关注,评论和鼓掌,并继续激励我们。 😀

我也写在http://iosdose.com/wp/

YouTube:https://bit.ly/2STjOF3

这是最终的源代码:)。