Ray*_*ond 35 ios xctest swift xctestcase
我有以下问题.我想在执行所有测试类之前执行一段代码.例如:我不希望我的游戏在执行期间使用SoundEngine单例,而是使用SilentSoundEngine.我想在一次测试中没有激活SilentSoundEngine.我所有的测试都是这样的:
class TestBasketExcercise : XCTestCase {
override func setUp() {
SilentSoundEngine.activate () // SoundEngine is a singleton
}
// The tests
}
Run Code Online (Sandbox Code Playgroud)
-Edit-大多数答案都针对为TestCase提供自定义超类.我正在寻找一种更通用,更清晰的方式来提供所有测试都需要执行的环境.是不是有一个"主要"功能/ Appdelegate喜欢功能的地方进行测试?
Mar*_*n R 56
从编写测试类和方法:
您也可以选择为类设置
(+ (void)setUp)
和拆卸添加自定义方法(+ (void)tearDown)
,这些方法在类中的所有测试方法之前和之后运行.
在Swift中,这将是class
方法:
override class func setUp() {
super.setUp()
// Called once before all tests are run
}
override class func tearDown() {
// Called once after all tests are run
super.tearDown()
}
Run Code Online (Sandbox Code Playgroud)
Jan*_*ash 47
TL; DR:
如前所述在这里,你应该在你的测试目标的Info.plist声明NSPrincipalClass.执行此类的init中的所有一次性设置代码,因为"XCTest在加载测试包时自动创建该类的单个实例",因此所有一次性设置代码将在加载时执行一次测试包.
更冗长一点:
要先在编辑中回答这个想法:
Afaik,main()
测试包没有,因为测试被注入到正在运行的主目标中,因此你必须main()
用编译时(或者至少一个)将一次性设置代码添加到主目标中运行时)检查目标是否用于运行测试.如果没有这个检查,你就有可能在SilentSoundEngine
正常运行目标时激活它,我猜这是不可取的,因为类名意味着这个声音引擎不会产生任何声音,说实话,谁想要这个?:)
然而,有一个AppDelegate
类似的功能,我将在我的答案结束时(如果你不耐烦,它在标题"另一个(更多XCTest特定的)方法"下).
现在,让我们将这个问题分成两个核心问题:
关于第1点:
正如@Martin R在他对你的问题的答案的评论中正确提到的+load
那样,从Swift 1.2(现在是古代历史:D)开始就不可能超越,并且dispatch_once()
在Swift 3中不再可用.
当你尝试使用时dispatch_once
,Xcode(> = 8)总是非常聪明,并建议你应该使用延迟初始化的全局变量.当然,这个术语global
往往让每个人都沉迷于恐惧和恐慌,但你当然可以通过将它们设为private/fileprivate来限制它们的范围(对于文件级声明也是如此),因此你不会污染你的命名空间.
Imho,它们实际上是一个非常漂亮的模式(仍然,剂量使毒药......)看起来像这样,例如:
private let _doSomethingOneTimeThatDoesNotReturnAResult: Void = {
print("This will be done one time. It doesn't return a result.")
}()
private let _doSomethingOneTimeThatDoesReturnAResult: String = {
print("This will be done one time. It returns a result.")
return "result"
}()
for i in 0...5 {
print(i)
_doSomethingOneTimeThatDoesNotReturnAResult
print(_doSomethingOneTimeThatDoesReturnAResult)
}
Run Code Online (Sandbox Code Playgroud)
这打印:
这将完成一次.它不会返回结果.
这将完成一次.它返回一个结果.
0
结果
1
结果
2
结果
3
结果
4
结果
5
结果
旁注:有趣的是,私有let在循环开始之前进行评估,你可以看到,因为如果不是这样的话,那么0就是第一次打印.当您对循环进行注释时,它仍将打印前两行(即评估let).
但是,我猜这是游乐场特定的行为,因为如此处和此处所述,全局变量通常在第一次被引用时被初始化,因此当您注释掉循环时不应该对它们进行求值.
(这实际上解决了第1点和第2点...)
由于公司来自Cupertino指出这里,有跑一次性预测试设置代码的方法.
要实现这一点,您需要创建一个虚拟安装类(可能称之为TestSetup?)并将所有一次性安装代码放入其init:
class TestSetup: NSObject {
override init() {
SilentSoundEngine.activate()
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,该类必须继承自NSObject,因为Xcode尝试通过使用实例化"该类的单个实例" +new
,因此如果该类是纯Swift类,则会发生这种情况:
*** NSForwarding: warning: object 0x11c2d01e0 of class 'YourTestTargetsName.TestSetup' does not implement methodSignatureForSelector: -- trouble ahead
Unrecognized selector +[YourTestTargetsName.TestSetup new]
Run Code Online (Sandbox Code Playgroud)
然后,将此类声明为test-bundles Info.plist文件中的PrincipalClass:
请注意,您必须使用完全限定的类名(即与TestSetup相比的YourTestTargetsName.TestSetup),因此该类由Xcode(Thanks,zneak ...)找到.
如XCTestObservationCenter文档中所述,"XCTest在加载测试包时会自动创建该类的单个实例",因此在加载测试包时,所有一次性安装代码都将在TestSetup的init中执行.
setUp
如果您只想对类中的所有 UI 测试调用该方法一次,在 Xcode 11 中您可以调用override class func setUp()
此方法是 Apple UI 测试文档的一部分: https://developer.apple.com/documentation/xctest/xctestcase/understanding_setup_and_teardown_for_test_methods
归档时间: |
|
查看次数: |
14742 次 |
最近记录: |