环境:iOS 9.3(真机),Mac OS X 10.11,KIF 3.4.2
KIF 3.4.2 本身自带了出错自动截图功能,关键代码如下:
- (void)failWithException:(NSException *)exception stopTest:(BOOL)stop
{
self.continueAfterFailure = YES;
[self recordFailureWithDescription:exception.description inFile:exception.userInfo[@"FilenameKey"] atLine:[exception.userInfo[@"LineNumberKey"] unsignedIntegerValue] expected:NO];
if (stop) {
[self writeScreenshotForException:exception];
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
Swizzle([XCTestCase class], @selector(_recordUnexpectedFailureWithDescription:exception:), @selector(KIF_recordUnexpectedFailureWithDescription:exception:));
});
[exception raise];
}
}
最终是调用了 UIApplication-KIFAdditions.m 里面的 - (BOOL)writeScreenshotForLine:(NSUInteger)lineNumber inFile:(NSString *)filename description:(NSString *)description error:(NSError **)error
方法进行截图和存储。
按照官方的说明,只需要配置一个环境变量 KIF_SCREENSHOTS
就能设定截图保存地址了进行出错自动截图了。然而真实情况没那么简单。
首先,这个环境变量不是 Mac 的环境变量,而是 Scheme 里面的环境变量。如下图:
KIF 中获取环境变量的关键代码:
NSString *outputPath = [[[NSProcessInfo processInfo] environment] objectForKey:@"KIF_SCREENSHOTS"];
原因嘛,很简单,KIF 是作为应用的一部分在手机上运行的,所以获取不到 mac 上的环境变量。
我想把截图存到项目代码文件夹里面,那么我打算把这个值放到 KIF_SCREENSHOTS 这个环境变量里:$(SRCROOT)/kif_screenshots
然后,就没有然后了。。。用例出错后,还是只有 log ,没有截图。。。
为啥呢???
和前面第一个坑差不多,因为运行位置是你的手机,所以能存储的目录其实就只有 sandbox 里面的目录,即 Documents 或者 Library 。
那么,得怎么改?难道要修改 KIF 的源码!?
改源码也不行,因为 sandbox 目录每次安装都不一样。。。
最后通过 Google 找到了变通方法:用 ~
。~
经过 outputPath = [outputPath stringByExpandingTildeInPath];
处理后会自动变成应用在真机上的 sandbox 目录,如 ~/Documents/kif_screenshots
会转换成
/var/mobile/Containers/Data/Application/EBE399B9-5E75-41EC-BCD2-E7F722364DBF/Documents/kif_screenshots
填完第二个坑后,终于有截图了。等等,截图放在真机上,我加入不了报告里啊!!!
同样通过 Google ,找到了解决方法:ios-deploy 。它能在非越狱机器上获取指定 app 的所有可读写目录内容。用法如下:
// Download the Documents directory of the app *only*
ios-deploy --download=/Documents --bundle_id my.app.id --to ./my_download_location
但有个不好的地方,每次都是传回来都是带目录结构的。转换也很简单,写了个简单的 shell 脚本:
# Set in app scheme's environment variable. It's folder on ios device
KIF_SCREENSHOTS=/Documents/KIF_SCREENSHOTS
# Path on Mac
OUTPUT_FOLDER=kif_screenshots
# bundle_id
BUNDLE_ID=com.xxx.photo
mkdir tmpKifScreenshot
ios-deploy --bundle_id $BUNDLE_ID --download=$KIF_SCREENSHOTS --to "tmpKifScreenshot"
cp tmpKifScreenshot$KIF_SCREENSHOTS/*.png $OUTPUT_FOLDER
rm -rf tmpKifScreenshot
最大的缺点就是获取不到 scheme 里面的 KIF_SCREENSHOTS 的值,所以变成 hard code 了。大家如果知道什么好方法欢迎分享出来~
ok,坑填完,截图到手了。接下来怎么用是后续的事情了~