XCode 内置了 OCUnit 单元测试框架,但目前最好用的测试框架应该是 GHUnit。通过 GHUnit + OCMock 组合,我们可以在 iOS 下进行较强大的单元测试功能。本文将演示如何在 XCode 4.2 下使用 OCUnit, GHUnit 和 OCMock 进行单元测试。

OCUnit

在 XCode 下新建一个 OCUnitProject 工程,选中 Include Unit Tests 选择框,

OCUnit 框架则会为我们自动添加 Unit Test 框架代码:

XCode 在 OCUnitProjectTests.m 中为我们自动生成了一个 Fail 的测试:

- (void)testExample
{
STFail(@"Unit tests are not implemented yet in OCUnitProjectTests");
}

让我们来运行 Test,看看效果:

从图中的红色下划线部分可以看出,测试没有通过,符合预期。我们只要像类 OCUnitProjectTests 一样编写继承自 SenTestCase 类的子类,在其中添加形式如:- (void) testXXX(); 的测试函数既可,注意必须是一个无参无返回类型且名称是以 test 为前缀的函数。

OCUnit 的有点是官方支持,于 XCode 集成的比较好。

GHUnit

GHUnit 是一个开源的单元测试框架,具有可视化界面,功能亦相当强大。Mark 写了一篇 OCUnit vs GHUnit的文章,有兴趣的童鞋可以看一看。OCMock 是由 Mulle Kybernetik 为 OS X 和 iOS 平台编写的遵循 mock object 理念的单元测试框架。

下面来介绍如何配置 GHUnit 和 OCMock

1,首先,创建一个名为 GHUnitProject 的单视图应用程序,注意:不要选中 Include Unit Tests 选择框。然后运行,应该出现白屏。

2,添加新的 test target,选中左边的工程名,点击右侧的 Add Target,新增一个名为 Tests 的 Empty Application 应用程序,让其附属于 GHUnitProject注意:不要选中 Include Unit Tests 选择框。

3,向 Tests 工程中(注意是 Tests 工程)添加 GHUnitIOS Framework。首先下载与 XCode 版本对应的 GHUnitIOS Framework。英文好的可以直接查看官方 iOS 版的安装文档:点此查看,跳过此第 3 节;否则请接着看。

3.1,解压 GHUnitIOS 框架到 GHUnitProject 下,让 GHUnitIOS.framework 与 Tests 在同一目录下。

3.2,回到 XCode,右击工程中的 Frameworks group,选中 Add Files to...菜单,选取 GHUnitIOS.framework ,注意 targets 要选择 Tests。

3.3,设置 Tests 的 Build Settings:在 Other Linker Flags 中增加两个 flag: -ObjC 和 -all_load。

3.4,删除 Tests 工程中的 UTSAppDelegate.h 和  UTSAppDelegate.m 两个文件;

3.5,修改 Tests 工程中的 main.m 为:

#import <UIKit/UIKit.h>
#import <GHUnitIOS/GHUnitIOSAppDelegate.h> int main(int argc, char *argv[])
{
@autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([GHUnitIOSAppDelegate class]));
}
}

3.6,选择编译目标 Tests>iPhone 5.0 Simulator,编译运行,应该能得到如下效果。目前我们还没有编写任何实际测试,所以列表为空。

4,编写 GHUnit 测试。向 Tests 工程中添加名为 GHUnitSampleTest 的 Objective C class。其内容如下:
GHUnitSampleTest.h

#import <GHUnitIOS/GHUnit.h> 

@interface GHUnitSampleTest: GHTestCase
{
} @end

GHUnitSampleTest.m

#import "GHUnitSampleTest.h"

@implementation GHUnitSampleTest

- (void)testStrings
{
NSString *string1 = @"a string";
GHTestLog(@"I can log to the GHUnit test console: %@", string1); // Assert string1 is not NULL, with no custom error description
GHAssertNotNULL(string1, nil); // Assert equal objects, add custom error description
NSString *string2 = @"a string";
GHAssertEqualObjects(string1, string2, @"A custom error message. string1 should be equal to: %@.", string2);
} @end

然后编译运行,点击 Run,效果如下:

图中的 All 栏显示所以的测试,Failed 栏显示没有通过的测试。强大吧,GHUnit。你可以向 GHUnitSampleTest 添加新的测试,比如:

- (void)testSimpleFail
{
GHAssertTrue(NO, nil);
}

我们可以向 Tests 添加更多测试类,只要该类是继承自 GHTestCase,且其中的测试方法都是无参无返回值且方法名字是以 test 为前缀即可。

 

OCMock

下面我们来添加 OCMock。

1,我们只能以静态库的方式来添加 OCMock。在 GHUnitTest 目录下新建 Libraries 目录,该目录是与 Tests 目录平级的。下载静态库文件,解压头文件至该目录下。
文件下载:头文件 libOCMock.a ,framework 文件:OCMock framework ,打开下载好的 ocmock-1.77.dmg,拷贝其中的‘Release/Library/Headers/OCMock’ 目录至 Libraries 下。最终目录结构如下:

2,在 GHUnitTest 工程中新建名为 Libraries 的 group,导入libOCMock.a 和目录 OCMock,注意 target 是 Tests。

3,设置 Tests 的 Build Setting。让 Libray Search Paths 包含 $(SRCROOT)/Libraries:

在 Header Search Paths 中增加 $(SRCROOT)/Libraries,并选中 Recursive 选择框。

4,编写 OCMock 测试。向 Tests 工程中添加名为 OCMockSampleTest 的 Objective C class。其内容如下:
OCMockSampleTest.h

#import <GHUnitIOS/GHUnit.h>

@interface OCMockSampleTest : GHTestCase

@end

OCMockSampleTest.m

#import "OCMockSampleTest.h"
#import <OCMock/OCMock.h> @implementation OCMockSampleTest // simple test to ensure building, linking,
// and running test case works in the project
- (void)testOCMockPass
{
id mock = [OCMockObject mockForClass:NSString.class];
[[[mock stub] andReturn:@"mocktest"] lowercaseString]; NSString *returnValue = [mock lowercaseString];
GHAssertEqualObjects(@"mocktest", returnValue,
@"Should have returned the expected string.");
} - (void)testOCMockFail
{
id mock = [OCMockObject mockForClass:NSString.class];
[[[mock stub] andReturn:@"mocktest"] lowercaseString]; NSString *returnValue = [mock lowercaseString];
GHAssertEqualObjects(@"thisIsTheWrongValueToCheck",
returnValue, @"Should have returned the expected string.");
} @end

编译运行,点击 Run,效果如下图。

至此,iOS 下的OCUnit,GHUnit,OCMock 单元测试介绍就到此结束了。当然还有其他一些测试框架,比如 google 出品的 GTM

XCode下的iOS单元测试的更多相关文章

  1. 爱上iOS单元测试系列之爱上她就要先了解她:单元测试入门

    前言 对于单元测试一开始我是拒绝的.单元测试是一个什么东东,因为我喜欢做iOS开发是因为喜欢写APP的啊,一切和这一目标不相干的东西我没兴趣啊,所以从事iOS开发几年都没去深入学习过单元测试(主要是之 ...

  2. 最新Xcode7.x环境下上架iOS App到AppStore 完整流程

    最新Xcode7.x环境下上架iOS App到AppStore 流程  part 1 前言部分 之前App要上架遇到些问题到网上搜上架教程发现都是一些老的版本的教程 ,目前iTunesConnect ...

  3. iOS单元测试1

    iOS单元测试1 iOS单元测试分为两种类型的测试: 应用测试.应用程序测试可以检查app的代码组件,比如计算机的算术运算的例子.你可以利用应用程序测试来确保你的UI空间控件保持原有位置,并且你的控件 ...

  4. 【转】Xcode中的iOS模拟器(iOS Simulator)的介绍和使用心得

    iOS模拟器简介 iOS功能简介 iOS模拟器,是在Mac下面开发程序时,开发iOS平台的程序时候,可以使用的辅助工具. 其功能是,帮你模拟iOS平台设备,在模拟器上运行对应的程序,以方便你没有实体设 ...

  5. Mac Xcode下配置OpenGL

    暂时搁置一下iOS,又要去弄一些杂七杂八的东西了,毕竟是学校的作业,还是要完成的. 作业是让我们用OpenGL做一个茶壶- -.而且要三维立体能旋转的那种. 好吧这些都不是重点,重点是我最终决定在Ma ...

  6. 使用Xcode + Python进行IOS运动轨迹模拟

    前言 在某些app中,需要根据用户的实时位置来完成某些事件 例如跑步打卡软件(步道乐跑).考勤打卡软件(叮叮).某些基于实时位置的游戏(Pokemon Go.一起来捉妖) 一般解决办法是通过使用安卓模 ...

  7. 【整理】Xcode中的iOS模拟器(iOS Simulator)的介绍和使用心得

    [整理]Xcode中的iOS模拟器(iOS Simulator)的介绍和使用心得 iOS模拟器简介 iOS功能简介 iOS模拟器,是在Mac下面开发程序时,开发iOS平台的程序时候,可以使用的辅助工具 ...

  8. Android studio下gradle Robolectric单元测试配置

    android studio下gradle Robolectric单元测试配置 1.Robolectric Robolectric是一个基于junit之上的单元测试框架.它并不依赖于Android提供 ...

  9. Xcode下的批量编辑

    说明:目前为止我找到三种查找与替换功能,如果有更多的方式,请在下面留言 第一种:我们常用的查找以及查找与替换功能 在Windows下,使用Ctrl+f 快捷键查找.用Ctrl+h来进行查找与替换功能. ...

随机推荐

  1. jQuery基础知识点(下)

    在实际开发中,jQuery的实践性非常强大.上一篇本人已经整理出了一部分基础知识点,该文即是对以上的补充和扩展. 1.表单值的操作 //获取文本框的值 //txt.value var val = $( ...

  2. 【DNS】DNS的几个基本概念

    一. 根域 就是所谓的“.”,其实我们的网址www.baidu.com在配置当中应该是www.baidu.com.(最后有一点),一般我们在浏览器里输入时会省略后面的点,而这也已经成为了习惯. 根域服 ...

  3. 排序(sortb)

    题目描述 懒得写题目背景了,就不写了. 有一个 $0, 1 \dots n − 1$ 的排列 $p_1, p_2 \dots p_n$,如果 $p_i ⊕ p_j ≤ a$(其中 $⊕$ 为按位异或) ...

  4. 用CSS模拟魔兽世界技能冷却的效果

    效果演示   上面的效果看起来还不错吧.在网页里,除了用Flash,我们还是有不少方法可以实现它. 显然这种效果不复杂,一张背景图片,加上前面带有透明度的多边形图层,在脚本控制下就可以转起来了.但问题 ...

  5. Codeforces 938.B Run For Your Prize

    B. Run For Your Prize time limit per test 1 second memory limit per test 256 megabytes input standar ...

  6. Codeforces 934.B A Prosperous Lot

    B. A Prosperous Lot time limit per test 1 second memory limit per test 256 megabytes input standard ...

  7. bzoj4059 [Cerc2012]Non-boring sequences

    传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=4059 [题解] 考虑分治.定义过程solve(l,r)为判断全在[l,r]范围内的所有连续子 ...

  8. 行为型设计模式之状态模式(State)

    结构 意图 允许一个对象在其内部状态改变时改变它的行为.对象看起来似乎修改了它的类. 适用性 一个对象的行为取决于它的状态, 并且它必须在运行时刻根据状态改变它的行为. 一个操作中含有庞大的多分支的条 ...

  9. JS 问题整理 (1)

    监听frame加载完毕 兼容Firefox/Opera/Safari/IE的处理方式,原文链接 var oFrm = document.getElementById('ifrm'); oFrm.onl ...

  10. fatal error LNK1104: 无法打开文件“LIBC.lib”错误(转)

    原文转自 http://blog.csdn.net/qq1028850792/article/details/41546043 方法一: 用VS2005重新编译某个工程的发生了链接错误,现在把这个解决 ...