单元测试对重构或后续业务的修改帮助非常大。
一、下面是两个单元测试的实例:
- 第一个是计算时间的,展示的时间距离现在过了多久。可以找一个固定时间,看时间比较返回的结果与预期是否相似。
- (void)test59SecondsAgo{
NSString * timeString = [self distanceUpLoadTimeWith:@"2019-12-14 10:59:01"];
NSAssert([timeString isEqualToString:@"59秒前"], @"");
}
- (void)test1MinutesAgo{
NSString * timeString = [self distanceUpLoadTimeWith:@"2019-12-14 10:59:00"];
NSAssert([timeString isEqualToString:@"1分钟前"], @"");
}
- (void)test24MinutesAgo{
NSString * timeString = [self distanceUpLoadTimeWith:@"2019-12-14 10:36:00"];
NSAssert([timeString isEqualToString:@"24分钟前"], @"");
}
- (void)test1HoursAgo{
NSString * timeString = [self distanceUpLoadTimeWith:@"2019-12-14 09:36:00"];
NSAssert([timeString isEqualToString:@"1小时前"], @"");
}
- (void)test1DayAgo{
NSString * timeString = [self distanceUpLoadTimeWith:@"2019-12-13 09:36:00"];
NSAssert([timeString isEqualToString:@"1天前"], @"");
}
//整一天前,边界
- (void)test1DayAgo2{
NSString * timeString = [self distanceUpLoadTimeWith:@"2019-12-13 11:00:00"];
NSAssert([timeString isEqualToString:@"1天前"], @"");
}
//整一月前,边界
- (void)test1MonthAgo{
NSString * timeString = [self distanceUpLoadTimeWith:@"2019-11-14 11:00:00"];
NSAssert([timeString isEqualToString:@"1月前"], @"");
}
- (void)test1MonthAgo2{
NSString * timeString = [self distanceUpLoadTimeWith:@"2019-11-13 11:00:00"];
NSAssert([timeString isEqualToString:@"1月前"], @"");
}
- (void)test3MonthAgo{
NSString * timeString = [self distanceUpLoadTimeWith:@"2019-09-13 11:00:00"];
NSAssert([timeString isEqualToString:@"3月前"], @"");
}
//整一年前,边界
- (void)test1YearsAgo{
NSString * timeString = [self distanceUpLoadTimeWith:@"2018-11-14 11:00:00"];
NSAssert([timeString isEqualToString:@"1年前"], @"");
}
- (void)test1YearsAgo2{
NSString * timeString = [self distanceUpLoadTimeWith:@"2018-11-13 11:00:00"];
NSAssert([timeString isEqualToString:@"1年前"], @"");
}
- (NSString *)distanceUpLoadTimeWith:(NSString *)timeString{
// NSDate *nowDate = [NSDate date];
//模拟一个固定的时间点
NSDate *nowDate = [self dateFromString:@"2019-12-14 11:00:00"];
NSDate * upLoadTime = [self dateFromString:timeString];
NSTimeInterval interval = [nowDate timeIntervalSinceDate:upLoadTime];
NSAssert(interval>0, @"时间必须是正的");
NSInteger y = interval/(60*60*24*30*12);
NSInteger months = interval/(60*60*24*30);
NSInteger d = interval/(60*60*24);
NSInteger h = interval/(60*60);
NSInteger minutes = interval/60;
NSInteger s = (long long)interval%60;
NSString * distanceString;
if (y>0) {
distanceString = [NSString stringWithFormat:@"%ld年前",(long)y];
}else if (months>0) {
distanceString = [NSString stringWithFormat:@"%ld月前",(long)months];
}else if (d>0) {
distanceString = [NSString stringWithFormat:@"%ld天前",(long)d];
}else if (h>0) {
distanceString = [NSString stringWithFormat:@"%ld小时前",(long)h];
}else if (minutes>0) {
distanceString = [NSString stringWithFormat:@"%ld分钟前",(long)minutes];
}else{
distanceString = [NSString stringWithFormat:@"%ld秒前",(long)s];
}
return distanceString;
}
- (NSDate *)dateFromString:(NSString *)dateString{
if (!dateString) {
return nil;
}
NSDateFormatter *dateFormatter = nil;
if (dateFormatter == nil) {
dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setLocale:[NSLocale currentLocale]];
[dateFormatter setDateFormat: @"yyyy-MM-dd HH:mm:ss"];
}
return [dateFormatter dateFromString:dateString];
}
- 第二个:从数组中选中当前的index,index-1,index+1的单元测试,用于列表浏览图片时展示当前和前后三张。包括本身只有一条数据,前后边界。如果后续要改成4个或5个,也是非常实用。
- (void)testArrayCount1Index0{
NSArray * array = @[@(1)];
[self indexprePostArrayWithArray:array index:0];
}
- (void)testArrayCount2Index0{
NSArray * array = @[@(1),@(2)];
[self indexprePostArrayWithArray:array index:0];
}
- (void)testArrayCount2Index1{
NSArray * array = @[@(1),@(2)];
[self indexprePostArrayWithArray:array index:1];
}
- (void)testArrayCount3Index0{
NSArray * array = @[@(1),@(2),@(3)];
[self indexprePostArrayWithArray:array index:0];
}
- (void)testArrayCount3Index1{
NSArray * array = @[@(1),@(2),@(3)];
[self indexprePostArrayWithArray:array index:1];
}
- (void)testArrayCount3Index2{
NSArray * array = @[@(1),@(2),@(3)];
[self indexprePostArrayWithArray:array index:2];
}
/*
返回index前后narray
怎么浏览三张,当前这张在中间;保证数组前后不能越界?
如果是在第0个位置,数量够时,取0,1,2;如果是最后一个位置,取最后一个位置
扩展:如果是4张,5张呢?算法的扩展性
*/
- (void)indexprePostArrayWithArray:(NSArray *)array index:(NSInteger)index{
NSAssert(index>=0 && index<array.count, @"index应在数组范围内");
NSInteger beign = index-1;
NSInteger end = index+1;
NSMutableArray * resultArray = [NSMutableArray arrayWithCapacity:3];
if (beign<0) {
end = end-beign;//减去负值
beign = 0;
if (end >= array.count) {
end = array.count - 1;
}
}else if(end>=array.count){
NSInteger absolute = end-(array.count-1);
beign = beign-absolute;
end = array.count-1;
if (beign<0) {
beign = 0;
}
}
NSAssert(beign>=0, @"begin不会小于0");
NSAssert(end<array.count, @"end不能大于等于count");
for (NSInteger i = beign; i<=end; i++) {
[resultArray addObject:array[I]];
}
if (array.count>=3) {
NSAssert(resultArray.count == 3, @"应该有3个");
}else{
NSAssert(resultArray.count == array.count, @"与数组个数相等");
}
}
二、环境问题
-
如果你的单元测试没有菱形运行按钮,可勾选对应选项
环境
-
如果是因为pod的第三方中有些文件找不到,可参考这篇:IOS开发中使用单元测试(OCUnit)测试集成pod库工程中的一些问题以及解决方案
-
我的问题有些类被添加到Tests中,导致报错。可根据错误信息不勾选没用到的类。
Tests
-
小技巧,如何一次性运行项目的所有单元测试
运行所有单元测试.png
总结:
单元测试对于复杂业务,或后续要修改业务,除了代码质量要过关,单元测试可以让你放心修改。
网友评论