iOS输入法—基于XCTest框架的异步测试
来源:互联网 发布:宇宙诞生之前知乎 编辑:程序博客网 时间:2024/06/04 08:45
苹果今年在Xcode 6中添加了XCTest框架此前漏掉的几项功能,这当中的异步测试功能大大方便了我们的测试工作。
如果我们的测试项目要执行一个异步任务,它可能会跑在其它的线程里,也可能会跑在主线程的RunLoop里,在这种时候我们应该如何去进行测试呢?来看一个非常简单的例子!
现在有一个web请求的功能需要测试。我们会开始web请求然后进入阻塞,接下来在程序完成的代码块中做一个测试断言。然而,鉴于没有web请求的情况下更谈不上响应,为了调用程序完成部分的代码我们就需要在断言之前确保被测试的方法已经在执行。
在通常情况下我们不会真的在测试时去做web响应,而是用一些工具来中断响应。不过在下面的例子里面我们需要更改一下规则——真正的完成一个web响应来进行测试。
我们使用了一个URL和一个程序完成块来模拟这个类的一个方法,它会下载URL所指的页面并调用这个程序块,如果成功会得到一个包含web页面的字符串,而发生错误的时候则是一个空字符串。
- (void)testCodeYouShouldNeverWrite
{
__block NSString *pageContents = nil;
[self.pageLoader requestUrl:@" http://123.sogou.com "
completionHandler:^(NSString *page) {
NSLog(@"The web page is %ld bytes long.", page.length);
// Test method ends before this test assertion is called
XCTAssert(pageContents.length > 0);
pageContents = page;
}];
// Nothing prevents the test method from returning before
// completionHandler is called.
}
很显然,这种测试方法是有问题的!
在Xcode 6之前的版本里面并没有内置XCTest,想使用Xcode测试的只能是在主线程的RunLoop里面使用一个while循环,然后一直等待响应或者直到timeout,下面就是这种旧方法的代码:
- (void)testAsyncTheOldWay
{
NSDate *timeoutDate = [NSDate dateWithTimeIntervalSinceNow:5.0];
__block BOOL responseHasArrived = NO;
[self.pageLoader requestUrl:@" http://123.sogou.com"
completionHandler:^(NSString *page) {
NSLog(@"The web page is %ld bytes long.", page.length);
responseHasArrived = YES;
XCTAssert(page.length > 0);
}];
while (responseHasArrived == NO && ([timeoutDate timeIntervalSinceNow] > 0)) {
CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.01, YES);
}
if (responseHasArrived == NO) {
XCTFail(@"Test timed out");
}
}
这个while循环在主线程里面每隔10毫秒会跑一次,直到有响应或者5秒之后超出响应时间限制才会跳出。这个方法十分有效而且看上去也不糟,但这并不意味着开发的终结——这个方法还是不够好。接下来说一个更加优化的办法。
在Xcode 6里,苹果以XCTestExpection类的方式向XCTest框架里添加了测试期望(test expection)。当我们实例化一个测试期望(XCTestExpectation)的时候,测试框架就会预计它在之后的某一时刻被实现。最终的程序完成代码块中的测试代码会调用XCTestExpection类中的fulfill方法来实现期望。
这一方法替代了我们之前例子里面使用responseHasArrived作为Flag的方式,这时我们让测试框架等待(有时限)测试期望通过XCTestCase的waitForExpectationsWithTimeout:handler:方法实现。如果完成处理的代码在指定时限里执行并调用了fulfill方法,那么就说明所有的测试期望在此期间都已经被实现。否则,这个测试就悲剧了,它会默默的存在程序中而不会被实现哪怕一次……
当然,失败结果并不意味着失败的测试,只有不明就里的测试结果才算失败的测试。
下面是使用XCTestExpection的示例:
(void)testWebPageDownload
{
XCTestExpectation *expectation =
[self expectationWithDescription:@"High Expectations"];
[self.pageLoader requestUrl:@"http://123.sogou.com”
completionHandler:^(NSString *page) {
NSLog(@"The web page is %ld bytes long.", page.length);
XCTAssert(page.length > 0);
[expectation fulfill];
}];
[self waitForExpectationsWithTimeout:5.0 handler:^(NSError *error) {
if (error) {
NSLog(@"Timeout Error: %@", error);
}
}];
}
在最后的代码段里面使用[expectation fulfill]来告知此次测试所期望的部分已经确切实现过了。
然后用waitForExpectationsWithTimeout:handler方法等待响应,这段会在接受响应之后执行……或者超时之后也会执行。
原文链接
如需转载该篇文章,请注明来自“搜狗测试”
- iOS输入法—基于XCTest框架的异步测试
- IOS XCTest使用异步测试
- iOS测试-XCTest
- IOS测试:XCTest小试牛刀
- 基于XCTest框架进行单元测试
- iOS开发笔记之二——XCTest单元测试框架的使用
- iOS 测试入门 XCTest入门(一)
- ios测试-使用XCTest进行单元测试
- iOS XCTest
- iOS开发:XCTest单元测试(附上一个单例的测试代码)
- iOS开发:XCTest单元测试(附上一个单例的测试代码)
- 【iOS】应用XCTest对异步任务进行单元测试
- XCTest框架定义的常用断言宏
- Xcode6下iOS单元测试——XCTest和GHUnit框架简介和比较
- ios测试-(一)使用XCTest进行单元测试
- ios测试-(一)使用XCTest进行单元测试
- iOS 单元测试- Xcode 7测试工具XCTest学习
- KIF框架在IOS输入法测试中的应用
- SQL Server 聚集索引在函数中使用以至失效(案例)
- Sogou输入法使用的代码静态检测工具
- Loadrunner调优之replay log介绍
- 搜狗输入法通过BUG流程优化,降低BUG修复分歧
- 搜狗自动化测试之介入时机
- iOS输入法—基于XCTest框架的异步测试
- LoadRunner脚本优化之服务器返回内容正确性判断
- Windows命令实现匿名邮件发送
- 愚人节篇:搜狗两枚测试开发小屌的对话
- 如何与多方沟通项目问题?
- #说说成长#测试小伙的内心独白
- 编程之各种奇技淫巧
- Android自动化工具Appium的使用
- 测试“攻城狮”的生活(搞笑版)