用于 UI 测试的台风交换组件
Typhoon swap assembly for UI testing
在 iOS 上运行 UI 测试时是否可以交换或修补程序集?目前我有一个项目,我在其中设置了 Typhoon 框架,我能够像这样修补程序集
var controller: HomeViewController!
override func setUp() {
super.setUp()
// setup assemblies
var blAssembly = BusinessLogicAssembly()
var ctrlAssembly = AppAssembly()
// setup patcher
let patcher = TyphoonPatcher()
patcher.patchDefinitionWithSelector("testManager", withObject: {return FakeManager()})
patcher.patchDefinition(blAssembly.testManager() as TyphoonDefinition, withObject: {
return FakeManager()})
let factory = TyphoonBlockComponentFactory(assemblies: [blAssembly, ctrlAssembly])
factory.attachPostProcessor(patcher)
// get controller
controller = factory.componentForKey("homeViewController") as HomeViewController
// force view to laod
let vcView = controller.view
}
这工作正常。它用存根修补 TestManager
。但在这种情况下,我手动调用我的视图控制器。当我运行 UI 测试时(当应用程序启动时,控制器在幕后处理)是否有办法修补程序集并提供 mock/stub?
例如,假设我有一个调用 Web 服务的视图控制器。 Web 服务逻辑包装在一个单独的 class 中,并使用 TyphoonAssembly
注入到视图控制器中。现在,对于我的 UI 测试,我不想联系我的实际 Web 服务,而只是证明示例数据。我想象通过创建我的 Web 服务存根 class 并返回测试数据来实现这一点。这个可以用Typhoon框架实现吗,因为我做不到,也找不到例子。
我正在使用 Swift,但 Objective-C 答案也可以(只要兼容)
现在 Typhoon 有几种方法可以将一个组件换成另一个。我们可以使用 TyphoonPatcher or modularize assemblies. Or we could even make a custom TyphoonDefinitionPostProcessor 或 TyphoonInstancePostProcessor.
problem/solution:
但是如果我正确理解你的问题,问题是正在使用应用程序样式(默认)类型的测试,其中:
- TEST_HOST 标志已设置。您的应用程序 类 对您的测试可见。
- 集成测试实例化它们自己的程序集,而不是使用应用程序程序集。虽然通常建议这样做,但重要的是要注意这是 一个单独的、附加的 程序集到主应用程序中使用的程序集。
如果您想从测试中修改主应用程序的程序集,我们可以使用 defaultFactory
。如果您使用的是 plist 集成:
为您的应用委托创建一个定义:
dynamic func appDelegate() -> AnyObject {
return TyphoonDefinition.withClass(AppDelegate.self) {
(definition) in
//This is a public instance var of type TyphoonComponentFactory
definition.injectProperty("assembly", with: self)
}
}
。 .然后在你的 AppDelegate 中:
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
factory.makeDefault()
}
。 . .现在在你的测试中或任何你需要的地方,你通过获取一个钩子来修补应用程序的程序集:
TyphoonComponentFactory *factory = [TyphoonComponentFactory defaultFactory];
[factory unload]; //clear out any singletons
//Now patch it
- 请注意,您可能需要先调用
factory.unload()
清除任何 TyphoonScopeSingleton
实例。
- 另请注意,如果您愿意,TyphoonPatcher 还允许取消修补或回退。
选择:
或者,更简单(我们建议尽可能简单),也许您可以使用不同的网络程序集启动应用程序,在应用程序 plist 中指定一组不同的程序集。
*注意:在 Objective-C 中,任何 TyphoonComponentFactory
都可以转换为程序集,反之亦然。这在 Swift 中是不允许的,因此可能会造成一些不便的限制。由 #253
致辞
在 iOS 上运行 UI 测试时是否可以交换或修补程序集?目前我有一个项目,我在其中设置了 Typhoon 框架,我能够像这样修补程序集
var controller: HomeViewController!
override func setUp() {
super.setUp()
// setup assemblies
var blAssembly = BusinessLogicAssembly()
var ctrlAssembly = AppAssembly()
// setup patcher
let patcher = TyphoonPatcher()
patcher.patchDefinitionWithSelector("testManager", withObject: {return FakeManager()})
patcher.patchDefinition(blAssembly.testManager() as TyphoonDefinition, withObject: {
return FakeManager()})
let factory = TyphoonBlockComponentFactory(assemblies: [blAssembly, ctrlAssembly])
factory.attachPostProcessor(patcher)
// get controller
controller = factory.componentForKey("homeViewController") as HomeViewController
// force view to laod
let vcView = controller.view
}
这工作正常。它用存根修补 TestManager
。但在这种情况下,我手动调用我的视图控制器。当我运行 UI 测试时(当应用程序启动时,控制器在幕后处理)是否有办法修补程序集并提供 mock/stub?
例如,假设我有一个调用 Web 服务的视图控制器。 Web 服务逻辑包装在一个单独的 class 中,并使用 TyphoonAssembly
注入到视图控制器中。现在,对于我的 UI 测试,我不想联系我的实际 Web 服务,而只是证明示例数据。我想象通过创建我的 Web 服务存根 class 并返回测试数据来实现这一点。这个可以用Typhoon框架实现吗,因为我做不到,也找不到例子。
我正在使用 Swift,但 Objective-C 答案也可以(只要兼容)
现在 Typhoon 有几种方法可以将一个组件换成另一个。我们可以使用 TyphoonPatcher or modularize assemblies. Or we could even make a custom TyphoonDefinitionPostProcessor 或 TyphoonInstancePostProcessor.
problem/solution:
但是如果我正确理解你的问题,问题是正在使用应用程序样式(默认)类型的测试,其中:
- TEST_HOST 标志已设置。您的应用程序 类 对您的测试可见。
- 集成测试实例化它们自己的程序集,而不是使用应用程序程序集。虽然通常建议这样做,但重要的是要注意这是 一个单独的、附加的 程序集到主应用程序中使用的程序集。
如果您想从测试中修改主应用程序的程序集,我们可以使用 defaultFactory
。如果您使用的是 plist 集成:
为您的应用委托创建一个定义:
dynamic func appDelegate() -> AnyObject {
return TyphoonDefinition.withClass(AppDelegate.self) {
(definition) in
//This is a public instance var of type TyphoonComponentFactory
definition.injectProperty("assembly", with: self)
}
}
。 .然后在你的 AppDelegate 中:
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
factory.makeDefault()
}
。 . .现在在你的测试中或任何你需要的地方,你通过获取一个钩子来修补应用程序的程序集:
TyphoonComponentFactory *factory = [TyphoonComponentFactory defaultFactory];
[factory unload]; //clear out any singletons
//Now patch it
- 请注意,您可能需要先调用
factory.unload()
清除任何TyphoonScopeSingleton
实例。 - 另请注意,如果您愿意,TyphoonPatcher 还允许取消修补或回退。
选择:
或者,更简单(我们建议尽可能简单),也许您可以使用不同的网络程序集启动应用程序,在应用程序 plist 中指定一组不同的程序集。
*注意:在 Objective-C 中,任何 TyphoonComponentFactory
都可以转换为程序集,反之亦然。这在 Swift 中是不允许的,因此可能会造成一些不便的限制。由 #253