如何通过Xcode 5中集成的XCTest框架进行简单的单元测试
XCTest
1.第一个单元测试
XCTest是Xcode 5中自带的测试框架
下面从一个Demo开始。首先用Xcode新建一个工程UnitTestDemo,工程目录结构如下:
可以看到工程下面多了一个叫UnitTestDemoTests的部分,Targets也多了一个UnitTestDemoTests,根据图标初步认为该Target跑的是一个框架。
这两个多出来的东西(相比Xcode 4没有Include Unit Tests的工程)就是用来做单元测试的,其特点是文件名或Target名都以Tests结尾。
再来看下UnitTestDemoTests.m中的代码:
- #import <XCTest/XCTest.h>
- @interface UnitTestDemoTests : XCTestCase
- @end
- @implementation UnitTestDemoTests
- - (void)setUp
- {
- [super setUp];
- // Put setup code here. This method is called before the invocation of each test method in the class.
- }
- - (void)tearDown
- {
- // Put teardown code here. This method is called after the invocation of each test method in the class.
- [super tearDown];
- }
- - (void)testExample
- {
- XCTFail(@"No implementation for \"%s\"", __PRETTY_FUNCTION__);
- }
- @end
该类继承自XCTestCase类,其中包含 三个方法:setUp,tearDown和testExample。
setUp方法用于在测试前设置好要测试的方法,tearDown则是在测试后将设置好的要测试的方法拆卸掉。
testExample顾名思义就是一个示例。
按快捷键Command + U进行单元测试,结果如下:
可以看到没有通过测试,在Issue Navigator和控制台都输出了错误信息:本类中的testExample方法没有实现。
实际上,这个错误是我们主动抛出来的。XCTFail是一个宏,其作用就是让测试失败,后面的No implementation for \"%s\"", __PRETTY_FUNCTION__就是要报告的错误信息,由我们自定。
报错总是让人不爽,好吧,我们将其注释掉,另外写一个测试方法,尝点甜头。为了规范,建议每个测试方法都写成“ - (void)testXXX ”形式,XXX表示要测试的方法名,并且无返回类型。
- //- (void)testExample
- //{
- // XCTFail(@"No implementation for \"%s\"", __PRETTY_FUNCTION__);
- //}
- - (void)testTrue {
- XCTAssert(1, @"Can not be zero");
- }
Command + U ,搞定:
注意左边的 Test Navigator, 绿色的标志表示 测试全部通过。
2.测试的顺序
如果在同一测试类文件中多写几个方法,例如:
- - (void)testTrue2 {
- NSLog(@"2222222222222222222222");
- XCTAssert(1, @"Can not be zero");
- }
- - (void)testTrue1 {
- NSLog(@"1111111111111111111111");
- XCTAssert(1, @"Can not be zero");
- }
- - (void)testTrue3 {
- NSLog(@"3333333333333333333333");
- XCTAssert(1, @"Can not be zero");
- }
- - (void)testAtrue {
- NSLog(@"0000000000000000000000");
- XCTAssert(1, @"Can not be zero");
- }
控制台部分输出:
- Test Case '-[UnitTestDemoTests testAtrue]' started.
- 2014-03-19 21:19:38.182 UnitTestDemo[7401:60b] 0000000000000000000000
- Test Case '-[UnitTestDemoTests testAtrue]' passed (0.001 seconds).
- Test Case '-[UnitTestDemoTests testTrue1]' started.
- 2014-03-19 21:19:38.183 UnitTestDemo[7401:60b] 1111111111111111111111
- Test Case '-[UnitTestDemoTests testTrue1]' passed (0.000 seconds).
- Test Case '-[UnitTestDemoTests testTrue2]' started.
- 2014-03-19 21:19:38.184 UnitTestDemo[7401:60b] 2222222222222222222222
- Test Case '-[UnitTestDemoTests testTrue2]' passed (0.013 seconds).
- Test Case '-[UnitTestDemoTests testTrue3]' started.
- 2014-03-19 21:19:38.196 UnitTestDemo[7401:60b] 3333333333333333333333
- Test Case '-[UnitTestDemoTests testTrue3]' passed (0.001 seconds).
- 可以看到无论我们怎样调换test方法的书写顺序,其测试顺序都是不变的。
目前初步的结论:测试方法执行的顺序与方法名中test后面的字符大小有关,小者优先,例如testA,testB1,testB2三个方法相继执行。
3.断言测试
下面一共18个断言(SDK中也是18个,其含义转自 ios UnitTest 学习笔记)
XCTFail(format…) 生成一个失败的测试;
XCTAssertNil(a1, format...)为空判断,a1为空时通过,反之不通过;
XCTAssertNotNil(a1, format…)不为空判断,a1不为空时通过,反之不通过;
XCTAssert(expression, format...)当expression求值为TRUE时通过;
XCTAssertTrue(expression, format...)当expression求值为TRUE时通过;
XCTAssertFalse(expression, format...)当expression求值为False时通过;
XCTAssertEqualObjects(a1, a2, format...)判断相等,[a1 isEqual:a2]值为TRUE时通过,其中一个不为空时,不通过 ;
XCTAssertNotEqualObjects(a1, a2, format...)判断不等,[a1 isEqual:a2]值为False时通过;
XCTAssertEqual(a1, a2, format...)判断相等(当a1和a2是 C语言标量、结构体或联合体时使用,实际测试发现NSString也可以);
XCTAssertNotEqual(a1, a2, format...)判断不等(当a1和a2是 C语言标量、结构体或联合体时使用);
XCTAssertEqualWithAccuracy(a1, a2, accuracy, format...)判断相等,(double或float类型)提供一个误差范围,当在误差范围(+/-accuracy)以内相等时通过测试;
XCTAssertNotEqualWithAccuracy(a1, a2, accuracy, format...) 判断不等,(double或float类型)提供一个误差范围,当在误差范围以内不等时通过测试;
XCTAssertThrows(expression, format...)异常测试,当expression发生异常时通过;反之不通过;(很变态)
XCTAssertThrowsSpecific(expression, specificException, format...) 异常测试,当expression发生specificException异常时通过;反之发生其他异常或不发生异常均不通过;
XCTAssertThrowsSpecificNamed(expression, specificException, exception_name, format...)异常测试,当expression发生具体异常、具体异常名称的异常时通过测试,反之不通过;
XCTAssertNoThrow(expression, format…)异常测试,当expression没有发生异常时通过测试;
XCTAssertNoThrowSpecific(expression, specificException, format...)异常测试,当expression没有发生具体异常、具体异常名称的异常时通过测试,反之不通过;
XCTAssertNoThrowSpecificNamed(expression, specificException, exception_name, format...)异常测试,当expression没有发生具体异常、具体异常名称的异常时通过测试,反之不通过
特别注意下 XCTAssertEqualObjects和 XCTAssertEqual 。
XCTAssertEqualObjects(a1, a2, format...)的判断条件是[a1 isEqual:a2]是否返回一个YES。
XCTAssertEqual(a1, a2, format...)的判断条件是a1 == a2是否返回一个YES。
对于后者,如果a1和a2都是基本数据类型变量,那么只有a1 == a2才会返回YES。例如下面代码中只有第二行可以通过测试:
- // 1.比较基本数据类型变量
- XCTAssertEqual(1, 2, @"a1 = a2 shoud be true"); // 无法通过测试
- XCTAssertEqual(1, 1, @"a1 = a2 shoud be true"); // 通过测试
但是,如果a1和a2都是指针,那么只有a1和a2指向同一个对象才会返回YES。例如下面的代码中:
- // 3.比较NSArray对象
- NSArray *array1 = @[@1];
- NSArray *array2 = @[@1];
- NSArray *array3 = array1;
- XCTAssertEqual(array1, array2, @"a1 and a2 should point to the same object"); // 无法通过测试
- XCTAssertEqual(array1, array3, @"a1 and a2 should point to the same object"); // 通过测试
array1和array2指向不同对象,无法通过测试。
这里比较奇怪的是, NSString另当别论:
- // 2.比较NSString对象
- NSString *str1 = @"1";
- NSString *str2 = @"1";
- NSString *str3 = str1;
- XCTAssertEqual(str1, str2, @"a1 and a2 should point to the same object"); // 通过测试
- XCTAssertEqual(str1, str3, @"a1 and a2 should point to the same object"); // 通过测试
尽管str1和str2指向不同的对象,但是二者的指针比较却能通过测试。在这里使用NSString要小心就是了。掌握了各个断言的含义,用起来就没什么大问题了。
如何通过Xcode 5中集成的XCTest框架进行简单的单元测试的更多相关文章
- 在前后端分离的SpringBoot项目中集成Shiro权限框架
参考[1].在前后端分离的SpringBoot项目中集成Shiro权限框架 参考[2]. Springboot + Vue + shiro 实现前后端分离.权限控制 以及跨域的问题也有涉及
- 【IDEA】单元测试:项目中引入JUnit测试框架+Mock简单了解
一.Junit 使用和说明: 参考:单元测试第三弹--使用JUnit进行单元测试-HollisChuang's Blog http://www.hollischuang.com/archives/17 ...
- Android中android-async-http开源网络框架的简单使用
android-async-http开源网络框架是专门针对Android在Apache的基础上构建的异步且基于回调的http client.所有的请求全在UI线程之外发生,而callback发生在创建 ...
- Spring Boot集成Reactor事件处理框架的简单示例
1. Reactor简介 Reactor 是 Spring 社区发布的基于事件驱动的异步框架,不仅解耦了程序之间的强调用关系,而且有效提升了系统的多线程并发处理能力. 2. Spring Boot集成 ...
- 在 Xcode 6 中使用矢量图( iPhone 6 置配 UI)
在 Xcode 6 中使用矢量图( iPhone 6 置配 UI) (本文转载:http://iosdeveloper.diandian.com/post/2014-09-25/40063062789 ...
- Bing Maps进阶系列八:在Bing Maps中集成OpenStreetMap地图
Bing Maps进阶系列八:在Bing Maps中集成OpenStreetMap地图 OSM(OpenStreetMap-开放街道地图)服务就是一种发布自己地图数据图片为服务的一种实现类型,开放街道 ...
- iOS原生项目中集成React Native
1.本文的前提条件是,电脑上已经安装了CocoaPods,React Native相关环境. 2.使用Xcode新建一个工程.EmbedRNMeituan [图1] 3.使用CocoaPods安装Re ...
- Unity3d 游戏中集成Firebase 统计和Admob广告最新中文教程
之前写过俩相关的教程,最近发现插件官方更新了不少内容,所以也更新一篇Firebase Admob Unity3d插件的教程,希望能帮到大家. Firebase Admob Unity3d插件是一个Un ...
- 使用Xcode过程中遇到的问题
前言:记录一下使用Xcode过程中遇到的问题 1.关于开发者的Team的问题,是选用自己的个人Team还是选用公司的付费的Team(本机环境:Xcode9 + iPad :iOS11.0.3) 问题: ...
随机推荐
- 2014年将会受欢迎的IT技能--你有多少哪?
据国外媒体报道,据Global Knowledge等十几家研究机构发布的2014年IT技能和薪金调查报告显示,2014年最受欢迎的十大IT技能如下: 1.编程与应用开发 据美国劳工统计局称,开发者和程 ...
- http://blog.sina.com.cn/s/blog_6145ed810102vr8k.html
http://blog.sina.com.cn/s/blog_6145ed810102vr8k.html
- TypeScript完全解读(26课时)_6.TypeScript完全解读-泛型
6.TypeScript完全解读-泛型 创建实例ts文件generics.ts 在index.ts内引入 fill是填充数组,创建的数组的元素数是times,填充的值就是接收的value的值 这里传入 ...
- 爬虫代码实现四:采用Hbase存储爬虫数据(2)
导入hbase的jar包,在maven仓库找:进入http://mavenrepository.com/,输入hbase client,选择apache hbase client, 点击进入,选择 点 ...
- Eclipse如何查看接口实现类快捷键
1.找到要打开的接口类 2.双击接口名选中 3.按Ctrl+T打开接口实现类 以List接口为例,如下所示
- Makefile研究 (一)—— 必备语法
摘自:http://blog.csdn.net/jundic/article/details/17535445 参考文档:http://blog.csdn.net/wrx1721267632/arti ...
- HTML学习笔记(五)框架
框架 通过使用框架,可以在同一个浏览器窗口中显示多个页面. eg: <frameset rows="50%,50%"> <frame src="/exa ...
- Android之打包签名
一.什么的是打包? 打包就是根据签名和其他标识生成安装包. 二.什么是签名? 1.在android应用文件(apk)中保存的一个特别字符串 2.用来标识不同的应用开发者:开发者A,开发者B 3.一个应 ...
- MFC——ComBox用法大全
Combo Box (组合框)控件很简单,可以节省空间.从用户角度来看,这个控件是由一个文本输入控件和一个下拉菜单组成的.用户可以从一个预先定义的列表里选择一个选项,同时也可以直接在文本框里面输入文本 ...
- ES6之Promise对象学习——8个例子学会Promise
目录 Promise 立即执行 Promise 三种状态 Promise 不可逆性 链式调用 Promise.then()回调异步性 Promise中的异常 Promise.resolve() res ...