![](https://i-blog.csdnimg.cn/blog_migrate/261e566c92d20062123fddff1dbff8fb.webp?x-image-process=image/format,png)
下的主流单元测试框架,主要有OCUnit、GHUnit、XCTest等几种,其中支持xcode4.x自带的OCUnit框架已经被Xcode5以上自带的的XCTest所取代;GHUnit是开源测试框架,它可以将测试报告以应用形式可视化输出到设备或模拟器上,也可以以文本形式输出到输出窗口。本文将介绍如何在Xcode中使用XCTest框架对代码进行单元测试。
给你的应用添加测试Target
在Xcode5以上的版本中创建新的应用和框架/库类会预配置一个测试目标。当你打开新工程,在测试导航面板上可以看到一个测试包、一个测试类和一个测试方法的模板,如图1所示。
但是如果打开一个比较老的版本的Xcode的工程就不会有测试目标了。这时如果我们需要添加测试Target的话,可以这样操作:点击待测试的目标,点击左下角的+号,并在弹出的对话框中按下图进行选择,然后一路Next就OK了。
测试目标,测试包,测试导航
在学习创建测试类和编写测试方法前,有必要看看测试导航面板。它对创建和运行测试工作极为重要。
测试导航面板罗列了测试包里的所有组件内容,并在一个层次列表里展示出测试类和测试方法。下面是一个工程的测试导航面板视图,包含了2个测试目标,展示了测试包、测试类以及测试方法的嵌套层。
创建测试类
可以使用加号按钮(+)和测试导航面板中的“NewTest Class”命令创建新测试类。
基于你在配置页面键入的测试类名,你添加的每个类都会使用一个名为ClassNameTests.m的文件被添加到项目中。
注意:所有测试类都是 XCTest 框架 XCTestCase 类的子类。
当你用Xcode5及以上版本创建工程时,一个测试目标和相关的测试包都会默认的被创建,名字根据工程名获得。比如创建名为 MyApp 的项目,则会自动生成名为 MyAppTests 的测试包,以及一个名为 MyAppTests 的测试类,关联在 MyAppTests.m 实例文件中。
-
测试类的结构
测试类包含如下的基本结构:
测试类用Objective-C实现。注意实现里包含了方法,比如setup和teardown的基本实例方法;这些方法是必须的。如果类中所有的测试方法都需要相同的代码,你可以定制setUp和tearDown来包含这些代码。你添加的代码在每一个测试方法的之前和之后执行。你可以有选择性的添加定制的设置(+ (void)setUp) 和卸载(+ (void)tearDown) 方法,他们在类里所有测试方法的之前和之后执行。
Xcode执行测试可以明确这些方法的使用,这正是我们接下来的内容要讨论的。
-
测试执行的流程
在执行测试的过程中,XCTest找到所有继承于 XCTestCase(它是测试类)的类,为每一个类运行它们的测试方法。
对于每个类来说,测试开始于运行类setup方法。对于每个测试方法来说,一个新的类实例被创建,它的实例setup方法就会执行。在跑完了测试方法之后,执行实例卸载方法。类中这样连续重复执行所有测试方法。在运行的类卸载了最后的测试方法后,Xcode会执行类卸载方法,并开始下一个类。这种序列一直重复直到跑完所有测试类的所有测试方法。简单来说,执行顺序是这样的:
类setup方法—>重复执行(实例setup方法—>测试方法—>实例tearDown方法)—> 类tearDown方法
-
编写测试方法
你通过编写测试方法把测试写到测试类中,一个测试方法是以 test 开头的测试类的实例方法,没有参数,返回 void,比如 testColorIsRed,测试方法调用工程中的代码,如果代码没有产生预期的结果,那么会用一系列的断言API报错。比如,一个函数返回值可能与预期值相比不同,或者你的测试方法使用了某个类里不适当的方法都将会抛出异常。“XCTestAssertions”描述了这些情况。
为了使测试方法能够正常访问被测试代码,引入正确的头文件到测试类中很重要。
当Xcode运行测试时,它调用的每个测试方法都是独立的。因此每个方法需要准备和清理辅助变量、结构以及与主题API进行交互的对象等。如果类中所有测试方法的某部分代码是相同的,你可以直接把它添加到必需的setUp 和 tearDown 的实例方法中。
XCTest断言
你的测试方法使用XCTest框架提供的断言来展示Xcode展示的测试结果。所有断言都有一个类似的形式:项目比较或逻辑表达式,一个失败结果字符串格式,和插入到字符串格式中的参数。
注意:所有断言的最后一个参数是 format... ,格式字符串和变量参数列表。XCTest为所有断言提供了默认的失败结果字符串,可使用参数传递到断言里。format 字符串提供了可选的额外的失败自定义描述,就可以进一步选择提供的描述。这个参数是可选的,也可以完全被忽略。
比如:
XCTAssertEqualObjects([calcViewController.displayField stringValue], @"10", @"Part 2 failed."); 阅读这段简单明了的描述,是说:“Indicate a failure when a string created from the value of thecontroller’s display field is not the same as the reference string ‘8’” .如果断言失败,那么Xcode在测试导航面板发出失败信号,然后Xcode会在issues导航面板、源码编辑器以及其他地方展示失败的描述。下面是源代码编辑器中典型的断言结果:
测试方法可以包含多个断言,如果任何断言包含失败报告,那么Xcode都发出的测试失败信号。
断言分为五种类型:无条件报错、等价测试、nil测试、布尔测试以及异常测试。
-
无条件报错
XCTFail.生成一个无条件报错。
XCTFail(format...)
-
等价测试
XCTAssertEqualObjects.当expression1不等于expression2时报错(或者一个对象为空,另一个不为空)。
XCTAssertEqualObjects(expression1, expression2, format...)
XCTAssertNotEqualObjects. 当expression1等于expression2时报错。
XCTAssertNotEqualObjects(expression1, expression2, format...)
XCTAssertEqual. 当expression1不等于expression2时报错,这个测试用于C语言的标量。
XCTAssertEqual(expression1, expression2, format...)
XCTAssertNotEqual. 当expression1等于expression2时报错,这个测试用于C语言的标量。
XCTAssertNotEqual(expression1, expression2, format...)
XCTAssertEqualWithAccuracy. 当expression1和expression2之间的差别高于accuracy将报错。这种测试适用于floats和doubles这些标量,两者之间的细微差异导致它们不完全相等,但是对所有的标量都有效。
XCTAssertEqualWithAccuracy(expression1, expression2, accuracy, format...)
XCTAssertNotEqualWithAccuracy. 当expression1和expression2之间的差别低于accuracy将产生失败。这种测试适用于floats和doubles这些标量,两者之间的细微差异导致它们不完全相等,但是对所有的标量都有效。
-
Nil(空)测试
XCTAssertNil. 当expression参数非nil时报错。
XCTAssertNil(expression, format...)
XCTAssertNotNil. 当expression参数为nil时报错。
XCTAssertNotNil(expression, format...)
-
Boolean测试
XCTAssertTrue. 当expression计算结果为false时报错。
XCTAssertTrue(expression, format...)
XCTAssert. 当expression计算结果为false时报错,与XCTAssertTrue同义。
XCTAssert(expression, format...)
XCTAssertFalse. 当expression计算结果为true报错。
XCTAssertFalse(expression, format...)
-
异常测试
XCTAssertThrows.当expression不抛出异常时报错。
XCTAssertThrows(expression, format...)
XCTAssertThrowsSpecific.当expression针对指定类不抛出异常时报错。
XCTAssertThrowsSpecific(expression, exception_class, format...)
XCTAssertThrowsSpecificNamed. 当expression针对特定类和特定名字不抛出异常时报错。对于AppKit框架或Foundation框架非常有用,抛出带有特定名字的NSException(NSInvalidArgumentException等等)。
XCTAssertThrowsSpecificNamed(expression, exception_class, exception_name, format...)
XCTAssertNoThrow. 当expression抛出异常时报错。
XCTAssertNoThrow(expression, format...)
XCTAssertNoThrowSpecific. 当expression针对指定类抛出异常时报错。任意其他异常都可以;也就是说它不会报错。
XCTAssertNoThrowSpecific(expression, exception_class, format...)
XCTAssertNoThrowSpecificNamed. 当expression针对特定类和特定名字抛出异常时报错。对于AppKit框架或Foundation框架非常有用,抛出带有特定名字的NSException(NSInvalidArgumentException等等)。
如需转载该篇文章,请注明来自“搜狗测试”