IOS开发笔记之三——XCTest单元测试框架的使用
2014-07-25 13:24
501 查看
第1章 前言
单元测试是一种白盒测试,白盒测试是一种细粒度的测试,具体到方法、函数和异常测试。顾名思义,单元测试也就是编码。在我们的软件的开发中,有时自己写了一些逻辑性较强的代码,没有人能够保证自己的代码第一次写出来就能达到要求。所以,需要去验证测试自己的这段代码,实际开发中,由于大家在项目工程中开发,想要程序走到自己的代码,需要很多繁琐的无关的步骤,这样如果要是需要做大量的测试时,针对性不强,就会浪费很多的无谓的时间。
当然,你可以另写一个demo,在demo中测试自己的代码逻辑。本次预研,就是为了可以在工程项目中直接通过调用你的方法来测试,要方便快捷很多。
本次预研历时约一周,由于项目开发等工作,所以,投入的时间间间断断,并没有投入足够集中的时间,单元测试是一个很大的领域,这篇文档只是带领入门,掌握简单的框架使用,可以方便测试你的逻辑代码。
此次主要介绍Xcode 5.0 自带的XCTest测试框架,属于部门开发任务,投入时间有限。后面若有时间,希望可以继续深入研究。
第2章 使用XCTest测试框架
在Xcode5.0以前的版本,Xcode自带的测试框架是OCUnit,这个已经被废止,但是经过验证,它还是可以继续使用的,在这里就暂不介绍了。
(1)添加XCTest到StockMaster工程中
如下图所示,通过创建target方式添加方式,需要File—>New—>Target—>IOS—>Other,选择Cocoa Touch Unit Testing Bundle模板。
选择自己要测试的Target,Type选择XCTest。点击Finish,之后你就可以在工程里面看到添加的测试框架目录,里面有默认生成的测试类。文件的目录如下图所示:
默认测试类中,有个自动生成的测试用例,这个测试用例默认是执行失败的。
(2) XCTest框架的设置
我们来尝试执行这个测试用例,再写一个默认执行通过的测试用例。如下:
然后,点击Edit Scheme,首先选择Destination目标设备(注意:逻辑单元测试只能在模拟器中测试,不能选择IOS Device)。
Run Enterprise**—>选择Debug
选择Test,Build Configuration选择Debug,并确保将测试用例勾选。
(3) 运行XCTest测试用例
Command + U运行测试或者选择Product—>Test,运行结果如下:
从图上可以看出,测试报告内容,包括测试用例执行时间、执行通过与否。当然要想仔细显示结果,需要我们写出详尽的测试用例。
第3章 怎样测试我们工程中的方法
当我们在自己写了一段逻辑比较复杂的逻辑时,而这段程序需要足够的测试,那么XCTest就可以发挥出它重要的作用了。
(1) 某个功能代码中,有个TestController类,类中有个字符串处理的方法
(NSMutableArray *) formatStringtoArray:(NSString *) wString segmentLetter:(NSString *) letter
它的作用是把NSString型的字符串,用letter字符分割开,分割的结果,存到NSMutableArray数组中。例如:
NSString 为“what,do,you,think,of,china,football”
处理后:
tempArray结果为:
what,
do,
you,
think,
of,
china,
football
共7个元素。
(2) 初始化工作
setup方法是初始化方法,tearDown方法是释放资源的方法,它们在每次调用测试方法之前和之后调用。初始化代码如下:
@interface Enterprise**_Tests : XCTestCase
@property(nonatomic, strong) TestController *testChatController;
@end
@implementation Enterprise**_Tests
- (void)setUp
{
[super setUp];
self.testController= [[TestController alloc] initWithNibName:@"TestController" bundle:nil];
}
- (void)tearDown
{
self.testController= nil;
[super tearDown];
}
(3) 书写测试用例,测试的质量如何直接取决于你的测试用例的质量。另外,测试用例的命名须要以test开头进行命名。对于这个方法我写了以下10个测试用例:
- (void)testFormatStringtoArray1
{
NSString *testString = @"what,do,you,think,of,china,football";
NSString *testSeg = @",";
NSMutableArray *testArray = [[NSMutableArray alloc] init];
testArray = [_testController formatStringtoArray:testString segmentLetter:testSeg];
NSLog(@"The formatted results:
%@",testArray);
NSUInteger countArray = [testArray count];
XCTAssertTrue([testArray count] == 7, @"期望值是:7,实际值是:%lu", (long)countArray);
}
- (void)testFormatStringtoArray2
{
NSString *testString = @"what,";
NSString *testSeg = @",";
NSMutableArray *testArray = [[NSMutableArray alloc] init];
testArray = [_testController formatStringtoArray:testString segmentLetter:testSeg];
NSLog(@"The formatted results:
%@",testArray);
NSUInteger countArray = [testArray count];
XCTAssertTrue([testArray count] == 1, @"期望值是:1,实际值是:%lu", (long)countArray);
}
- (void)testFormatStringtoArray3
{
NSString *testString = @",do";
NSString *testSeg = @",";
NSMutableArray *testArray = [[NSMutableArray alloc] init];
testArray = [_testController formatStringtoArray:testString segmentLetter:testSeg];
NSLog(@"The formatted results:
%@",testArray);
NSUInteger countArray = [testArray count];
XCTAssertTrue([testArray count] == 1, @"期望值是:1,实际值是:%lu", (long)countArray);
}
- (void)testFormatStringtoArray4
{
NSString *testString = @",";
NSString *testSeg = @",";
NSMutableArray *testArray = [[NSMutableArray alloc] init];
testArray = [_testController formatStringtoArray:testString segmentLetter:testSeg];
NSLog(@"The formatted results:
%@",testArray);
NSUInteger countArray = [testArray count];
XCTAssertTrue([testArray count] == 0, @"期望值是:0,实际值是:%lu", (long)countArray);
}
- (void)testFormatStringtoArray5
{
NSString *testString = @",,,";
NSString *testSeg = @",";
NSMutableArray *testArray = [[NSMutableArray alloc] init];
testArray = [_testController formatStringtoArray:testString segmentLetter:testSeg];
NSUInteger countArray = [testArray count];
XCTAssertTrue([testArray count] == 0, @"期望值是:0,实际值是:%lu", (long)countArray);
}
- (void)testFormatStringtoArray6
{
NSString *testString = @"what,,do,,,you,,,think..,of,;;china;;..,..football?";
NSString *testSeg = @",";
NSMutableArray *testArray = [[NSMutableArray alloc] init];
testArray = [_testController formatStringtoArray:testString segmentLetter:testSeg];
NSUInteger countArray = [testArray count];
XCTAssertTrue([testArray count] == 7, @"期望值是:7,实际值是:%lu", (long)countArray);
}
- (void)testFormatStringtoArray7
{
NSString *testString = @"whatdoyouthinkofchinafootball?";
NSString *testSeg = @",";
NSMutableArray *testArray = [[NSMutableArray alloc] init];
testArray = [_testController formatStringtoArray:testString segmentLetter:testSeg];
NSLog(@"The formatted results:
%@",testArray);
NSUInteger countArray = [testArray count];
XCTAssertTrue([testArray count] == 1, @"期望值是:1,实际值是:%lu", (long)countArray);
}
- (void)testFormatStringtoArray8
{
NSString *testString = @"what.do,you,think, ,of, ,china, ,football?";
NSString *testSeg = @",";
NSMutableArray *testArray = [[NSMutableArray alloc] init];
testArray = [_testController formatStringtoArray:testString segmentLetter:testSeg];
NSLog(@"The formatted results:
%@",testArray);
NSUInteger countArray = [testArray count];
XCTAssertTrue([testArray count] == 6, @"期望值是:6,实际值是:%lu", (long)countArray);
}
- (void)testFormatStringtoArray9
{
NSString *testString = @"what|,do,|you|,think, ,of, ,china, ,football?";
NSString *testSeg = @",";
NSMutableArray *testArray = [[NSMutableArray alloc] init];
testArray = [_testController formatStringtoArray:testString segmentLetter:testSeg];
NSLog(@"The formatted results:
%@",testArray);
NSUInteger countArray = [testArray count];
XCTAssertTrue([testArray count] == 7, @"期望值是:7,实际值是:%lu", (long)countArray);
}
- (void)testFormatStringtoArray10
{
NSString *testString = @"what,,do,,you,,think,,, ,of,,,,,,,,,,,,,,,,,, ,china, ,football?";
NSString *testSeg = @",";
NSMutableArray *testArray = [[NSMutableArray alloc] init];
testArray = [_testController formatStringtoArray:testString segmentLetter:testSeg];
NSLog(@"The formatted results:
%@",testArray);
NSUInteger countArray = [testArray count];
XCTAssertTrue([testArray count] == 7, @"期望值是:7,实际值是:%lu", (long)countArray);
}
经过command + U运行编译,输出的测试报告如下:
10个测试用例,只通过了5个,可见我当初的那段代码写的是多么有问题以及单元测试的必要性。
第4章 XCTest测试框架基本原理介绍
(1)测试运行时序图
前面已经说过,测试类中会调用setup和tearDown方法,setUp是初始化方法,tearDown是释放资源的方法,他们在每次调用测试方法之前和之后调用。
因此,在测试类运行的生命周期中,这两个方法可能会多次运行,它们的时序图如图所示:
(2)框架中的断言测试(参考相关文档)
下面一共18个断言(SDK中也是18个,部分宏已经测试过):
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语言标量、结构体或联合体时使用,实际测试发现NSString也可以);
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没有发生具体异常、具体异常名称的异常时通过测试,反之不通过
XCTAssertEqualObjects(a1, a2, format...)的判断条件是[a1 isEqual:a2]是否返回一个YES。
XCTAssertEqual(a1, a2, format...)的判断条件是a1 == a2是否返回一个YES。
第5章 你可能遇到的问题以及解决方案
1、 找不到相关文件问题
(1)问题描述
(2)问题分析与参考解决方案
当你在自己创建的target类中调用测试类时,被测试类有可能会链接其他文件库,而这些库并没有被链接到target中,此时需要手动添加缺少文件的所在的文件目录,
由于我们的工程链接库比较复杂,我也不确定文件链接的关系,目前只有这样机械的手工添加。
找到缺少文件目录,例如:
/Users/ztli/Desktop/***/***/MTIA/MTIA/
操作如下:
注意:
(1)此时被测试类的TestController 类右侧的Target Membership中的Enterprise** Tests不要轻易选上。
(2)如果上述方法仍然不能解决此问题,可以直接将缺少的文件找到,放置到测试类文件的Supporting Files文件夹下。
2、测试Configuration选择问题
(1) 问题描述:
在创建好测试target时,会出现类似如下的错误提示:
Undefined symbols for architecture i386:
"_OBJC_CLASS_$_TestController", referenced from:
objc-class-ref in Enterprise**_Tests.o
ld: symbol(s) not found for architecture i386
clang: error: linker command failed with exit code 1 (use -v to see invocation)
(2) 问题分析及参考解决方案:
造成这个问题一般与你的Scheme配置造成,进入Scheme编辑页面,保证如下图的选择配置:
Build选项,对应target勾选(至少选择Test)
Test选项,Build configuration选择Debug,而不是release。
3、格式字符串问题
(1) 问题描述:
XCTAssertTrue ([testArray count] == 7, @"期望值是:7,实际值是:%d",[testArray count]);
使用XCTAssertTrue时,会有以上的格式警示,如图所示。
(2) 问题分析与参考解决方案:
The cause of the warning in this case comes from the use of a %d in the format specifier which expects a signed 32-bit integer. However the value supplied was an NSInteger which will be a 64-bit integer with the 64-bit runtime. The fix in this case is to
explicitly specify a long integer in the format string ( %ld ) and cast the NSInteger to a long:
NSUInteger countArray = [testArray count];
XCTAssertTrue([testArray count] == 7, @"期望值是:7,实际值是:%lu", (long)countArray);
(3)参考链接:
http://www.tuicool.com/articles/vumyEra
第6章 小结
这本只是针对Xcode 5.0自带框架的XCTest的介绍,IOS的单元测试还有很多功能强大的第三方开源测试框架,
例如GHUnit、OCMock等,它们拥有自己特长。值得去深入研究,本文暂不进行介绍,望以后还可以继续研究。
单元测试是一种白盒测试,白盒测试是一种细粒度的测试,具体到方法、函数和异常测试。顾名思义,单元测试也就是编码。在我们的软件的开发中,有时自己写了一些逻辑性较强的代码,没有人能够保证自己的代码第一次写出来就能达到要求。所以,需要去验证测试自己的这段代码,实际开发中,由于大家在项目工程中开发,想要程序走到自己的代码,需要很多繁琐的无关的步骤,这样如果要是需要做大量的测试时,针对性不强,就会浪费很多的无谓的时间。
当然,你可以另写一个demo,在demo中测试自己的代码逻辑。本次预研,就是为了可以在工程项目中直接通过调用你的方法来测试,要方便快捷很多。
本次预研历时约一周,由于项目开发等工作,所以,投入的时间间间断断,并没有投入足够集中的时间,单元测试是一个很大的领域,这篇文档只是带领入门,掌握简单的框架使用,可以方便测试你的逻辑代码。
此次主要介绍Xcode 5.0 自带的XCTest测试框架,属于部门开发任务,投入时间有限。后面若有时间,希望可以继续深入研究。
第2章 使用XCTest测试框架
在Xcode5.0以前的版本,Xcode自带的测试框架是OCUnit,这个已经被废止,但是经过验证,它还是可以继续使用的,在这里就暂不介绍了。
(1)添加XCTest到StockMaster工程中
如下图所示,通过创建target方式添加方式,需要File—>New—>Target—>IOS—>Other,选择Cocoa Touch Unit Testing Bundle模板。
选择自己要测试的Target,Type选择XCTest。点击Finish,之后你就可以在工程里面看到添加的测试框架目录,里面有默认生成的测试类。文件的目录如下图所示:
默认测试类中,有个自动生成的测试用例,这个测试用例默认是执行失败的。
(2) XCTest框架的设置
我们来尝试执行这个测试用例,再写一个默认执行通过的测试用例。如下:
然后,点击Edit Scheme,首先选择Destination目标设备(注意:逻辑单元测试只能在模拟器中测试,不能选择IOS Device)。
Run Enterprise**—>选择Debug
选择Test,Build Configuration选择Debug,并确保将测试用例勾选。
(3) 运行XCTest测试用例
Command + U运行测试或者选择Product—>Test,运行结果如下:
从图上可以看出,测试报告内容,包括测试用例执行时间、执行通过与否。当然要想仔细显示结果,需要我们写出详尽的测试用例。
第3章 怎样测试我们工程中的方法
当我们在自己写了一段逻辑比较复杂的逻辑时,而这段程序需要足够的测试,那么XCTest就可以发挥出它重要的作用了。
(1) 某个功能代码中,有个TestController类,类中有个字符串处理的方法
(NSMutableArray *) formatStringtoArray:(NSString *) wString segmentLetter:(NSString *) letter
它的作用是把NSString型的字符串,用letter字符分割开,分割的结果,存到NSMutableArray数组中。例如:
NSString 为“what,do,you,think,of,china,football”
处理后:
tempArray结果为:
what,
do,
you,
think,
of,
china,
football
共7个元素。
(2) 初始化工作
setup方法是初始化方法,tearDown方法是释放资源的方法,它们在每次调用测试方法之前和之后调用。初始化代码如下:
@interface Enterprise**_Tests : XCTestCase
@property(nonatomic, strong) TestController *testChatController;
@end
@implementation Enterprise**_Tests
- (void)setUp
{
[super setUp];
self.testController= [[TestController alloc] initWithNibName:@"TestController" bundle:nil];
}
- (void)tearDown
{
self.testController= nil;
[super tearDown];
}
(3) 书写测试用例,测试的质量如何直接取决于你的测试用例的质量。另外,测试用例的命名须要以test开头进行命名。对于这个方法我写了以下10个测试用例:
- (void)testFormatStringtoArray1
{
NSString *testString = @"what,do,you,think,of,china,football";
NSString *testSeg = @",";
NSMutableArray *testArray = [[NSMutableArray alloc] init];
testArray = [_testController formatStringtoArray:testString segmentLetter:testSeg];
NSLog(@"The formatted results:
%@",testArray);
NSUInteger countArray = [testArray count];
XCTAssertTrue([testArray count] == 7, @"期望值是:7,实际值是:%lu", (long)countArray);
}
- (void)testFormatStringtoArray2
{
NSString *testString = @"what,";
NSString *testSeg = @",";
NSMutableArray *testArray = [[NSMutableArray alloc] init];
testArray = [_testController formatStringtoArray:testString segmentLetter:testSeg];
NSLog(@"The formatted results:
%@",testArray);
NSUInteger countArray = [testArray count];
XCTAssertTrue([testArray count] == 1, @"期望值是:1,实际值是:%lu", (long)countArray);
}
- (void)testFormatStringtoArray3
{
NSString *testString = @",do";
NSString *testSeg = @",";
NSMutableArray *testArray = [[NSMutableArray alloc] init];
testArray = [_testController formatStringtoArray:testString segmentLetter:testSeg];
NSLog(@"The formatted results:
%@",testArray);
NSUInteger countArray = [testArray count];
XCTAssertTrue([testArray count] == 1, @"期望值是:1,实际值是:%lu", (long)countArray);
}
- (void)testFormatStringtoArray4
{
NSString *testString = @",";
NSString *testSeg = @",";
NSMutableArray *testArray = [[NSMutableArray alloc] init];
testArray = [_testController formatStringtoArray:testString segmentLetter:testSeg];
NSLog(@"The formatted results:
%@",testArray);
NSUInteger countArray = [testArray count];
XCTAssertTrue([testArray count] == 0, @"期望值是:0,实际值是:%lu", (long)countArray);
}
- (void)testFormatStringtoArray5
{
NSString *testString = @",,,";
NSString *testSeg = @",";
NSMutableArray *testArray = [[NSMutableArray alloc] init];
testArray = [_testController formatStringtoArray:testString segmentLetter:testSeg];
NSUInteger countArray = [testArray count];
XCTAssertTrue([testArray count] == 0, @"期望值是:0,实际值是:%lu", (long)countArray);
}
- (void)testFormatStringtoArray6
{
NSString *testString = @"what,,do,,,you,,,think..,of,;;china;;..,..football?";
NSString *testSeg = @",";
NSMutableArray *testArray = [[NSMutableArray alloc] init];
testArray = [_testController formatStringtoArray:testString segmentLetter:testSeg];
NSUInteger countArray = [testArray count];
XCTAssertTrue([testArray count] == 7, @"期望值是:7,实际值是:%lu", (long)countArray);
}
- (void)testFormatStringtoArray7
{
NSString *testString = @"whatdoyouthinkofchinafootball?";
NSString *testSeg = @",";
NSMutableArray *testArray = [[NSMutableArray alloc] init];
testArray = [_testController formatStringtoArray:testString segmentLetter:testSeg];
NSLog(@"The formatted results:
%@",testArray);
NSUInteger countArray = [testArray count];
XCTAssertTrue([testArray count] == 1, @"期望值是:1,实际值是:%lu", (long)countArray);
}
- (void)testFormatStringtoArray8
{
NSString *testString = @"what.do,you,think, ,of, ,china, ,football?";
NSString *testSeg = @",";
NSMutableArray *testArray = [[NSMutableArray alloc] init];
testArray = [_testController formatStringtoArray:testString segmentLetter:testSeg];
NSLog(@"The formatted results:
%@",testArray);
NSUInteger countArray = [testArray count];
XCTAssertTrue([testArray count] == 6, @"期望值是:6,实际值是:%lu", (long)countArray);
}
- (void)testFormatStringtoArray9
{
NSString *testString = @"what|,do,|you|,think, ,of, ,china, ,football?";
NSString *testSeg = @",";
NSMutableArray *testArray = [[NSMutableArray alloc] init];
testArray = [_testController formatStringtoArray:testString segmentLetter:testSeg];
NSLog(@"The formatted results:
%@",testArray);
NSUInteger countArray = [testArray count];
XCTAssertTrue([testArray count] == 7, @"期望值是:7,实际值是:%lu", (long)countArray);
}
- (void)testFormatStringtoArray10
{
NSString *testString = @"what,,do,,you,,think,,, ,of,,,,,,,,,,,,,,,,,, ,china, ,football?";
NSString *testSeg = @",";
NSMutableArray *testArray = [[NSMutableArray alloc] init];
testArray = [_testController formatStringtoArray:testString segmentLetter:testSeg];
NSLog(@"The formatted results:
%@",testArray);
NSUInteger countArray = [testArray count];
XCTAssertTrue([testArray count] == 7, @"期望值是:7,实际值是:%lu", (long)countArray);
}
经过command + U运行编译,输出的测试报告如下:
10个测试用例,只通过了5个,可见我当初的那段代码写的是多么有问题以及单元测试的必要性。
第4章 XCTest测试框架基本原理介绍
(1)测试运行时序图
前面已经说过,测试类中会调用setup和tearDown方法,setUp是初始化方法,tearDown是释放资源的方法,他们在每次调用测试方法之前和之后调用。
因此,在测试类运行的生命周期中,这两个方法可能会多次运行,它们的时序图如图所示:
(2)框架中的断言测试(参考相关文档)
下面一共18个断言(SDK中也是18个,部分宏已经测试过):
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语言标量、结构体或联合体时使用,实际测试发现NSString也可以);
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没有发生具体异常、具体异常名称的异常时通过测试,反之不通过
XCTAssertEqualObjects(a1, a2, format...)的判断条件是[a1 isEqual:a2]是否返回一个YES。
XCTAssertEqual(a1, a2, format...)的判断条件是a1 == a2是否返回一个YES。
第5章 你可能遇到的问题以及解决方案
1、 找不到相关文件问题
(1)问题描述
(2)问题分析与参考解决方案
当你在自己创建的target类中调用测试类时,被测试类有可能会链接其他文件库,而这些库并没有被链接到target中,此时需要手动添加缺少文件的所在的文件目录,
由于我们的工程链接库比较复杂,我也不确定文件链接的关系,目前只有这样机械的手工添加。
找到缺少文件目录,例如:
/Users/ztli/Desktop/***/***/MTIA/MTIA/
操作如下:
注意:
(1)此时被测试类的TestController 类右侧的Target Membership中的Enterprise** Tests不要轻易选上。
(2)如果上述方法仍然不能解决此问题,可以直接将缺少的文件找到,放置到测试类文件的Supporting Files文件夹下。
2、测试Configuration选择问题
(1) 问题描述:
在创建好测试target时,会出现类似如下的错误提示:
Undefined symbols for architecture i386:
"_OBJC_CLASS_$_TestController", referenced from:
objc-class-ref in Enterprise**_Tests.o
ld: symbol(s) not found for architecture i386
clang: error: linker command failed with exit code 1 (use -v to see invocation)
(2) 问题分析及参考解决方案:
造成这个问题一般与你的Scheme配置造成,进入Scheme编辑页面,保证如下图的选择配置:
Build选项,对应target勾选(至少选择Test)
Test选项,Build configuration选择Debug,而不是release。
3、格式字符串问题
(1) 问题描述:
XCTAssertTrue ([testArray count] == 7, @"期望值是:7,实际值是:%d",[testArray count]);
使用XCTAssertTrue时,会有以上的格式警示,如图所示。
(2) 问题分析与参考解决方案:
The cause of the warning in this case comes from the use of a %d in the format specifier which expects a signed 32-bit integer. However the value supplied was an NSInteger which will be a 64-bit integer with the 64-bit runtime. The fix in this case is to
explicitly specify a long integer in the format string ( %ld ) and cast the NSInteger to a long:
NSUInteger countArray = [testArray count];
XCTAssertTrue([testArray count] == 7, @"期望值是:7,实际值是:%lu", (long)countArray);
(3)参考链接:
http://www.tuicool.com/articles/vumyEra
第6章 小结
这本只是针对Xcode 5.0自带框架的XCTest的介绍,IOS的单元测试还有很多功能强大的第三方开源测试框架,
例如GHUnit、OCMock等,它们拥有自己特长。值得去深入研究,本文暂不进行介绍,望以后还可以继续研究。
相关文章推荐
- iOS开发笔记--开源播放框架ijkplayer(iOS版)使用教程
- iOS开发学习笔记:使用xcode里的单元测试,放在STAssert…里面的语句无法使用自动完成功能
- IOS开发笔记-定时器的使用
- 使用Mootools开发JavaScript单元测试框架javascript
- iOS开发笔记--TableView的详细使用
- 【Cocos2d-X开发学习笔记】第06期:渲染框架之精灵类(CCSprite)的使用
- 【Cocos2d-X开发学习笔记】第03期:渲染框架之导演类(CCDirector)的使用
- 【iOS-Cocos2d游戏开发之十一】使用Box2d物理系统以及在cocos2d框架添加Box2d物理系统lib包的方法
- GHUnit IOS开发第三方单元测试工具 使用方法
- IOS开发学习笔记(十一)——ObjectC中集合类型的使用
- iOS开发学习笔记 -- (四)使用Table
- 【Cocos2d-X开发学习笔记】第04期:渲染框架之场景类(CCScene)的使用
- IOS开发基础教程学习笔记3 使用Tab Bar切换视图
- 【iOS-Cocos2d游戏开发之十一】使用Box2d物理系统以及在cocos2d框架添加Box2d物理系统lib包的方法
- 【Cocos2d-X开发学习笔记】第02期:渲染框架之节点类(CCNode)的使用
- java开发框架_ZK使用笔记一
- IOS开发笔记(五)---基础控件的使用(Text Filed ,Image View,Slider等)
- 【iOS开发笔记23/50】使用ARC时,如果不加strong,有时会给出警告
- 【Cocos2d-X开发学习笔记】第05期:渲染框架之布景层类(CCLayer)的使用
- 【Cocos2d-X开发学习笔记】第03期:渲染框架之导演类(CCDirector)的使用