• XCode 下的 iOS 单元测试


    XCode 下的 iOS 单元测试
    CC 许可,转载请注明出处

    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 的测试:

    1. - (void)testExample  
    2. {  
    3.     STFail(@"Unit tests are not implemented yet in OCUnitProjectTests");  
    4. }  

    让我们来运行 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.1,删除 Tests 工程中的 UTSAppDelegate.h 和  UTSAppDelegate.m 两个文件;

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

    1. #import <UIKit/UIKit.h>  
    2. #import <GHUnitIOS/GHUnitIOSAppDelegate.h>  
    3.   
    4. int main(int argc, char *argv[])  
    5. {  
    6.     @autoreleasepool {  
    7.         return UIApplicationMain(argc, argv, nil, NSStringFromClass([GHUnitIOSAppDelegate class]));  
    8.     }  
    9. }  

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

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

    1. #import <GHUnitIOS/GHUnit.h>   
    2.   
    3. @interface GHUnitSampleTest: GHTestCase  
    4. {  
    5. }  
    6.   
    7. @end  
    GHUnitSampleTest.m
    1. #import "GHUnitSampleTest.h"  
    2.   
    3. @implementation GHUnitSampleTest  
    4.   
    5. - (void)testStrings  
    6. {         
    7.     NSString *string1 = @"a string";  
    8.     GHTestLog(@"I can log to the GHUnit test console: %@", string1);  
    9.       
    10.     // Assert string1 is not NULL, with no custom error description  
    11.     GHAssertNotNULL(string1, nil);  
    12.       
    13.     // Assert equal objects, add custom error description  
    14.     NSString *string2 = @"a string";  
    15.     GHAssertEqualObjects(string1, string2, @"A custom error message. string1 should be equal to: %@.", string2);  
    16. }  
    17.   
    18. @end  

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

    图中的 All 栏显示所以的测试,Failed 栏显示没有通过的测试。强大吧,GHUnit。你可以向 GHUnitSampleTest 添加新的测试,比如:
    1. - (void)testSimpleFail  
    2. {  
    3.     GHAssertTrue(NO, nil);  
    4. }  

    我们可以向 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

    1. #import <GHUnitIOS/GHUnit.h>  
    2.   
    3. @interface OCMockSampleTest : GHTestCase  
    4.   
    5. @end  
    OCMockSampleTest.m
    1. #import "OCMockSampleTest.h"  
    2. #import <OCMock/OCMock.h>  
    3.   
    4. @implementation OCMockSampleTest  
    5.   
    6. // simple test to ensure building, linking,   
    7. // and running test case works in the project  
    8. - (void)testOCMockPass  
    9. {  
    10.     id mock = [OCMockObject mockForClass:NSString.class];  
    11.     [[[mock stub] andReturn:@"mocktest"] lowercaseString];  
    12.       
    13.     NSString *returnValue = [mock lowercaseString];  
    14.     GHAssertEqualObjects(@"mocktest", returnValue,   
    15.                          @"Should have returned the expected string.");  
    16. }  
    17.   
    18. - (void)testOCMockFail  
    19. {  
    20.     id mock = [OCMockObject mockForClass:NSString.class];  
    21.     [[[mock stub] andReturn:@"mocktest"] lowercaseString];  
    22.       
    23.     NSString *returnValue = [mock lowercaseString];  
    24.     GHAssertEqualObjects(@"thisIsTheWrongValueToCheck",   
    25.                          returnValue, @"Should have returned the expected string.");  
    26. }  
    27.   
    28. @end  

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


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

    参考资料:
    OCMock: http://ocmock.org/
    Unit Testing in Xcode 4- use OCUnit and SenTest instead of GHUnit
    GHUnit Reference: http://gabriel.github.com/gh-unit/



  • 相关阅读:
    jQuery 集合 搜索操作(父辈元素搜索、同辈元素搜索、子元素搜索)
    struts <s:form action=""> 和 <s:submit action=""> 的区别
    654. 最大二叉树
    701. 二叉搜索树中的插入操作
    617. 合并二叉树
    98. 验证二叉搜索树
    236. 二叉树的最近公共祖先
    700. 二叉搜索树中的搜索
    235. 二叉搜索树的最近公共祖先
    105. 从前序与中序遍历序列构造二叉树
  • 原文地址:https://www.cnblogs.com/javawebsoa/p/2458450.html
Copyright © 2020-2023  润新知