前言
前文说过,所谓单元测试就是针对代码的最小单元进行测试。通俗的说,就是每写一个类,都编写相应的测试类;每写一个属性、函数,对属性、函数的每一个特性编写相应的测试方法。
单元测试的思想是,通过外部调用要测试的单元,看给定的输入是否能有预期的输出。Xcode对单元测试进行了充分的支持和集成,XCTest框架、测试导航栏、测试覆盖率。
本文主要介绍一下单元测试的一些基本概念、方法和流程。对于MVC设计模式来说,MVC三者之间的概念区别是非常大的,那么这三者的单元测试也各有各的方法和特点。后面的文章将分别针对MVC的单元测试编写进行一些经验性的总结
在Xcode中使用单元测试
下面通过一个最简单的案例,来演示如何在Xcode中使用单元测试,可分为如下5步:
-
创建测试target
在新建项目时,大家应该有注意到一个叫作“Include Unit Tests”的可勾选项,最简单的创建测试target的方式,就是直接在创建项目时勾选。如果要在已有项目中添加测试target,可以通过菜单栏File -> New -> Target -> iOS Unit Testing Bundle 来添加。
如果添加完毕,项目导航器里多了一个名为“XXXTests”的组,同时项目多了相应的target。
-
创建测试类
有了测试target后,包里已经默认生成了一个测试类。可以通过 New -> File(或快捷键cmd+n) 选择Unit Test Case Class 来新建测试类,注意新建类时要选择步骤1中创建的单元测试group和target。
打开测试类文件后可以发现,我们实际上创建了一个XCTest
框架的XCTestCase
子类。由于测试文件和源代码在不同的bundle中,所以需要手动导入源代码bundle:@testable import XXX
。
创建测试方法
首先注意到类已自动重写了setUp()
和tearDown()
两个方法,setUp()
在执行测试方法之前调用,用来进行必要的配置和准备工作;tearDown()
在执行测试方法之后调用,用来进行必要的清理和扫尾工作。
接下来是最重要的编写测试方法,如测试一个Student
类的init()
方法,预期该方法将生成一个Student实例,其属性name
会被设置为默认值“No Name”。
首先要注意的是测试方法的命名:必须以test
开头,Xcode才会将其作为测试方法对待;建议将命名分为三个部分,以_
隔开,第一部分test
,第二部分为要测试的方法,第三部分为要测试的特性。在本例中就可以命名为test_Init_NameShouldSetDefaultValue()
在方法内部经过必要的处理后,通过XCTAssert
的一系列方法,如XCTAssertEqual
XCTAssertNotNil
等,对预期结果和执行结果进行断言。
func test_Init_NameShouldSetDefaultValue() {
let s = Student()
XCTAssertEqual(s.name, "No Name")
}执行测试
执行测试可以通过菜单栏的 Product -> Test (或快捷键 cmd + u) ,点击测试导航器中测试方法的三角或点击测试方法左侧边栏的空心方块来执行查看执行结果
若执行测试通过,测试方法左侧边栏的方块将变成绿色的勾,若未通过,会变成红色的叉。
另可以通过测试导航器来查看,测试导航器是Xcode的导航器的第5个标签项,可以查看已有测试用例的结构、新建测试target和class、执行测试及显示执行结果。