在Xcode的unit testing,它运行的应用程序?
我遇到了一个我以前没遇到过的奇怪的问题。
当你做cmd + U来运行你的unit testing(例如OCUnit),它实际上调用main.m,新的appDelegate和运行应用程序,就好像你已经按下CMD + R?
我只问,因为我在这个DataLayer背后使用CoreData。 我在我的testing中嘲笑DataLayer成功,但是一旦我实现了一个实际调用CoreData的getAll方法,app / xcode抛出一个关于被pipe对象模型的exception不能为零。 我明白,但我没有意义,实际上新的DataLayer类,我已经在我的mainviewcontroller loadView方法中调用DataLayer的getAll方法放置一个断点。 testing无关紧要,因为这是一个模拟对象,但显然它是调用真实的实例。
所以回到我的问题,当按下cmd + U它也运行应用程序,然后运行testing?
该应用程序实际上运行,但有一个技巧,你可以用来阻止它运行。
int main(int argc, char* argv[]) { int returnValue; @autoreleasepool { BOOL inTests = (NSClassFromString(@"SenTestCase") != nil || NSClassFromString(@"XCTest") != nil); if (inTests) { //use a special empty delegate when we are inside the tests returnValue = UIApplicationMain(argc, argv, nil, @"TestsAppDelegate"); } else { //use the normal delegate returnValue = UIApplicationMain(argc, argv, nil, @"AppDelegate"); } } return returnValue; }
这里是Sulthan的答案的一个变体,它使用了XCTest 5生成的testing类的默认值XCTest。
int main(int argc, char * argv[]) { @autoreleasepool { BOOL runningTests = NSClassFromString(@"XCTestCase") != nil; if(!runningTests) { return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); } else { return UIApplicationMain(argc, argv, nil, @"TestAppDelegate"); } } }
这将进入main.m,这应该在标准项目布局的支持文件下。
然后在你的testing目录中添加:
TestAppDelegate.h
#import <Foundation/Foundation.h> @interface TestAppDelegate : NSObject<UIApplicationDelegate> @end
TestAppDelegate.m
#import "TestAppDelegate.h" @implementation TestAppDelegate @end
在Swift中,我优先绕过application: didFinishLaunchingWithOptions
的正常执行pathapplication: didFinishLaunchingWithOptions
:
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { guard normalExecutionPath() else { window = nil return false } // regular setup return true } private func normalExecutionPath() -> Bool { return NSClassFromString("XCTestCase") == nil }
guard
内部的代码将删除从故事板创build的任何视图。
如果你使用Swift(你可能没有main.c
),你必须执行以下步骤:
1:删除AppDelegate.swift
中的@UIApplicationMain
2:创build一个空的TestingAppDelegate.swift
import UIKit class TestingAppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? }
3:创build一个名为main.swift
的文件:
import Foundation import UIKit let isRunningTests = NSClassFromString("XCTestCase") != nil if isRunningTests { UIApplicationMain(C_ARGC, C_ARGV, nil, NSStringFromClass(TestingAppDelegate)) } else { UIApplicationMain(C_ARGC, C_ARGV, nil, NSStringFromClass(AppDelegate)) }
是的,您的testing目标对应用目标具有目标依赖性,所以当您按Cmd + U或Cmd + Shift + U时,应用目标将被build立。
我使用Tomasz Bak的方法加上dwb答案的一些代码,并拿出以下内容:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { BOOL runningTests = NSClassFromString(@"XCTestCase") != nil; if (runningTests) { self.window.rootViewController = [UIViewController new]; return true; } // Your normal code below this .... }
我发现了另一个解决问题的办法:
int main(int argc, char * argv[]) { @autoreleasepool { return UIApplicationMain(argc, argv, nil, ({ ![NSProcessInfo processInfo].environment[@"XCTestConfigurationFilePath"] ? @"AppDelegate" : nil; })); } }
从这里: http : //qualitycoding.org/app-delegate-for-tests/#comment-63984
使用xCode 7和xCtool
xctool能够在不运行应用程序的情况下执行unit testing。
为了得到这个工作,
1。 更新目标设置以在没有主机应用的情况下运行
select您的项目 – >然后testing目标 – >将主机应用程序设置为无。
2.安装xctool,如果你没有的话。
brew install xctool
3.使用xctool使用terminal运行testing。
xctool -workspace yourWorkspace.xcworkspace -scheme yourScheme run-tests -sdk iphonesimulator
上面的优秀答案build议在运行时dynamic更改应用程序委托。
我做的小修改是通过查询NSProcessInfo
来检测unit testing运行 。 好处是你不需要有一个可以被检测到的类来看unit testing是否正在运行。
int main(int argc, char * argv[]) { // Put your App delegate class here. const Class appDelegateClass = [ATAppDelegate class]; NSDictionary *const environmentDictionary = [[NSProcessInfo processInfo] environment]; const BOOL runningUnitTests = environmentDictionary[@"XCInjectBundleInto"] != nil; NSString *delegateName = runningUnitTests ? nil : NSStringFromClass(appDelegateClass); @autoreleasepool { return UIApplicationMain(argc, argv, nil, delegateName); } }
@"XCInjectBundleInto"
的@"XCInjectBundleInto"
属性是unit testing包的path,由Xcode设置。
- 在SDK“iOS 10.0”中,产品类型“应用程序”需要代码签名 – StickerPackExtension需要开发团队错误
- 使用xcodebuild构buildiOS应用程序而无需使用codesign
- Xcode卡在“您的应用程序正在上传”
- Xcode不断要求input密码才能使用系统密钥链
- iOS的崩溃日志捕获,debugging信息..抓住并通过电子邮件发送到开发团队
- Swift – 获取设备的IP地址
- 在iOS 8.0.0 GM Safari上通过HTTP上传文件失败
- 如何更改uitableview删除button的文字
- UIPinchGestureRecognizer中的捏放大的最大/最小比例 – iPhone iOS