iOS Xcode自带单元测试框架XCTest进行逻辑测试和异步测试

使用Kiwi框架进行测试,参考这篇Kiwi简单使用-硬币

demo代码地址

        在写完代码或者修改一个功能后,我们需要对修改的代码进行测试,看看修改或者添加的代码有没有bug,这时候你可能会重新运行程序,操作到相应的函数界面,下断点,看看代码是否正常工作,可是每次都运行代码进行测试的效率肯定不如只测试这一个函数的效率来的高,单元测试就是为你的某一个函数或者功能进行单独测试的功能。

什么时候用到单元测试

逻辑测试:测试逻辑方法
异步测试:测试耗时方法(用来测试包含多线程的方法)
性能测试:测试某一方法运行所消耗的时间

废话不多说,下面介绍下简单的单元测试流程:

1.创建UnitTest的target

有两种方法,一个是新建工程时勾选单元测试选项


第二种就是创建工程时没有创建UnitTest的target的话,点击File-->new-->target-->iOS-->iOS Unit Testing Bundle创建

创建完之后项目中多了一个.m和plist文件如图,我们的测试代码就写在这里,

如果项目中需要测试的函数很多,建议自己再创建.m文件进行分类测试,这样以后再查找测试代码时方便查找。创建方法跟创建类一样,command+N 然后选择iOS-Unit Test Case Clase 选择subclass为XCTestCase,类名自己定义。

2.函数用法

点进.m的测试文件里我们看到有四个函数,用法分别如下:

setUp--初始化的代码,在测试方法之前调用

tearDown --释放测试用例的资源代码,在每个测试用例执行后调用

testExample--测试用例的方法,测试代码写在这个方法里,可以自己重新添加,但是要以test开头

testPerformanceExample--测试性能的方法

3.简单的测试用法

在Viewcontrollerl里创建一个方法如下

- (NSInteger)addA:(NSInteger)a andB:(NSInteger)b
{
    return a+b;
}

在测试文件中引入头文件,创建实例,

#import <XCTest/XCTest.h>
#import "ViewController.h"

@interface UnitTestDemoTests : XCTestCase
@property (nonatomic,strong) ViewController *vc;
@end
@implementation UnitTestDemoTests

- (void)setUp {
    [super setUp];
    //初始化的代码,在测试方法调用之前调用
    self.vc = [ViewController new];
}

- (void)tearDown {
    [super tearDown];
    // 释放测试用例的资源代码,这个方法会每个测试用例执行后调用
    self.vc = nil;
}

添加测试代码

- (void)testExample {
    // 测试用例的例子,可以自己重新添加,注意一定要test开头
    NSInteger a = 1, b = 2;
    XCTAssertTrue([self.vc addA:a andB:b]==3 , @"测试不通过");
}

XCTAssertTrue(expression, format...)当expression求值为TRUE时通过,如果不通过则显示format。

PS:其他断言语句用法如下:

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语言标量、结构体或联合体时使用, 判断的是变量的地址,如果地址相同则返回TRUE,否则返回NO);
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没有发生具体异常、具体异常名称的异常时通过测试,反之不通过

4.运行测试

comman+U运行整个测试文件或者点击测试方法左边的小方块运行单个测试方法

运行后如果测试通过,提示test succeeded,如果测试失败则显示断言中的提示。

PS:单元测试运行时出现问题 Main Thread Checker: UI API called on a background thread: XXX

这是因为需要在主线程执行的代码被放在了子线程里面,可以按command+shift+逗号,调出的菜单中选择Test,在右边选择Diagnostics下面Main Thread Checker关闭该选项,或者找到出问题的代码并修改。参考博客  参考博客2

5.简单的代码性能测试

- (void)testPerformanceExample {
    // 测试性能的方法,有Instrument调试工具之后,其实这个没毛用
    [self measureBlock:^{
        // 需要测试性能的代码
        for (int i = 0; i < 1000; i++) {
            NSLog(@"%d" , i);
        }
    }];
}
运行后,右边显示代码运行时间

6.简单的异步请求测试--单元测试异步测试

- (void)testExample {
    
    XCTestExpectation *expectation = [self expectationWithDescription:@"request"];
    // 获得请求管理者
    AFHTTPSessionManager *mgr = [AFHTTPSessionManager manager];
    mgr.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"text/html",nil];
    // 发送 GET 请求
    [mgr GET:@"http://www.weather.com.cn/adat/sk/101110101.html" parameters:nil success:^(NSURLSessionDataTask *task, id responseObject) {
        XCTAssertNotNil(responseObject, @"返回出错");
        [expectation fulfill];
    } failure:^(NSURLSessionDataTask *task, NSError *error) {
        XCTAssertNil(error, @"请求出错");
        [expectation fulfill];
    }];
    
    // 在case最后使用这一方法,此时单测程序会阻塞到这里;除非达到了超时时间(秒单位)或者是回调函数中调用了fulfill,单测程序才会结束
    // 若是超时情况,则认为case失败;若通过expectation的fulfill触发,则case通过
    //等待回掉方法,5秒超时触发测试失败
    [self waitForExpectationsWithTimeout:5 handler:^(NSError * _Nullable error) {
        //测试结束
        NSLog(@"test case over");
    }];
    
}


单元测试详细解析

参考博客2


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值