iOS异步测试

简介

在iOS做单元测试的时候,写异步方法的时候是比较恶心的,系统提供的API简直不能忍,先看一下

//1. 设置一个Expectation
XCTestExpectation *expectation = [self expectationWithDescription:@"testSomeThing"];

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
    // 3. 异步操作在3秒后完成,完成后调用fulfill,而等待的方法则继续运行");
    [expectation fulfill];
});

//2. 等待Expectation结束,超过超时时间则测试失败
[self waitForExpectationsWithTimeout:30 handler:nil];

用法

系统提供的API太过于简陋,有时候我们不希望超时的时候就立即停止测试,而是可以获取是否超时的结果,或者提供一些重试的机制,在这里封装了几个异步方法,基于MainRunLoop,提供重试机制,通过扩展XCTestCase实现,可以通过Pod导入

pod 'XCTestCaseAsync'

具体代码见后面链接,先看看用法

  1. 异步测试
//1. wait with a async block
[self waitWithAsync:^(FinishBlock  _Nonnull complete) {
    // async method
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        // set finish flag, finish async
        complete();
    });
}];
  1. 超时测试
//2. timeout
BOOL success = [self waitWithTimeout:3 asyncBlock:^(FinishBlock  _Nonnull complete) {
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(15 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        complete();
    });
}];
if (success) {
    NSLog(@"block execute success");
} else {
    NSLog(@"timeout");
}
  1. 重试
//3. retry
BOOL success = [self waitWithRetryTimes:3 asyncBlock:^(CompleteBlock  _Nonnull complete) {
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{        
        NSLog(@"failure");
        complete(NO);
    });
}];
if (success) {
    NSLog(@"block execute success");
} else {
    NSLog(@"block execute fail after retry");
}
  1. swift版本如下
// 1. async test
self.wait { (complete) in
    let delay = DispatchTime.now() + .seconds(1)
    DispatchQueue.main.asyncAfter(deadline: delay, execute: {
        complete()
    })
}

// 2. timeout test
let success = self.wait(withTimeout: 3) { (complete) in
    let delay = DispatchTime.now() + .seconds(5)
    DispatchQueue.main.asyncAfter(deadline: delay, execute: {
        complete()
    })
}

// 3. retry test
let success = self.wait(withRetryTimes: 3) { (complete) in
    let delay = DispatchTime.now() + .seconds(1)
    DispatchQueue.main.asyncAfter(deadline: delay, execute: {    
        print("failure")
        complete(false);
    })
}

代码

详细代码见这里

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 135,269评论 19 139
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 174,638评论 25 709
  • 这个世界太快了,认真的人像傻子。为什么从来都是认真的人被嘲笑呢,你装作什么都不在乎的样子才最可怜。尽然觉得不在乎的...
    ff7295735936阅读 194评论 0 0
  • 看了很多心理方面的文章之后,有时候会恍然大悟,“原来我这暴脾气都是原生家庭的问题啊。”自己一切的不好仿佛都...
    米粒粒1阅读 247评论 2 8
  • 锦江龙阅读 163评论 0 0