使用信号量的 XCTest 单异步设置
XCTest Single Asynchronous SetUp With Semaphores
我正在通过 Alamofire 测试 API。我需要对服务器进行一次调用以准备集成测试。一旦完成,我就可以开始 运行ning 测试了。
通常的override setUp()
每次测试都是运行,所以我不想那样做。
因此,我选择覆盖 class setUp()
,如下所述:https://developer.apple.com/reference/xctest/xctestcase
这很好,但是现在,我不能再使用标准了waitForExpectations
。 (在 class override setUp())
中,我收到几个编译器错误,告诉我我不再调用相同的 waitForExpectations
因为我在 class 方法中,而不是测试用例。
为了解决这个问题,我想像这样使用信号量:
class ServiceLayerTests: XCTestCase {
static var apiService: APIService = APIService()
let sessionManager = SessionManager(serverTrustPolicyManager: ServerTrustPolicyManager(policies: ["http://localhost:3000/": .disableEvaluation]))
static var companyManger: UserWebResource?
static var companyManagerID = -1
override class func setUp() {
apiService.baseURL = "http://localhost:3000/"
beginIntegrationTests()
}
class func beginIntegrationTests() {
var semaphore = DispatchSemaphore(value: 0)
apiService.beginIntegrationTests(completion: {resource, error in
if let resource = resource {
if let manager = resource as? UserWebResource {
companyManger = manager
companyManagerID = manager.id
semaphore.signal()
}
}
})
_ = semaphore.wait(timeout: DispatchTime.distantFuture)
}
}
这不起作用。在引擎盖下,有一个对服务器的 alamo fire 调用,它响应用户以用于集成测试。我确实看到服务器在旋转,所以我知道实际的通信正在进行,但我从未进入完成关闭。
我怀疑我不明白 Swift 是如何处理信号量的,而且我不知何故造成了死锁。如果有人有更好的解决方案,我将非常乐意听到。
I get several compiler errors that tell me that I am no longer calling
the same waitForExpectations
because I am in a class method, not a
test case
有道理。您可能想要的是重构,以便您处于测试用例中:
override class func setUp() {
apiService.baseURL = "http://localhost:3000/"
}
func testIntegrationTests() {
let urlExpectation = expectation(description: "INTEGRATION TEST")
apiService.beginIntegrationTests(completion: {resource, error in
// ...
urlExpectation.fulfill()
})
// not sure what an acceptable timeout would be, I chose this at random
waitForExpectations(timeout: 25) { error in
if let error = error {
print("Error: \(error.localizedDescription)")
}
}
}
可以在这里找到包含一些好的测试示例的最佳资源之一:http://nshipster.com/xctestcase/
您可以将期望创建为执行一次性设置并在完成时执行的惰性变量。
在每次测试 setUp()
函数开始时,您可以等待该期望。
None 的测试将 运行 直到完成,并且初始设置将 运行 只有一次。
class WaitForSetup_Tests: XCTestCase {
lazy var initialSetupFinished: XCTestExpectation = {
let initialSetupFinished = expectation(description: "initial setup finished")
initialSetupTask() { // your setup task that executes this closure on completion
initialSetupFinished.fulfill()
return
}
return initialSetupFinished
}()
override func setUp() {
wait(for: [initialSignOutFinished], timeout: 2.0)
// do your per-test setup here
}
}
注意:此解决方案避免使用 override class function setUp()
class 方法,因为除了在实例中,我不知道如何使用期望。
我正在通过 Alamofire 测试 API。我需要对服务器进行一次调用以准备集成测试。一旦完成,我就可以开始 运行ning 测试了。
通常的override setUp()
每次测试都是运行,所以我不想那样做。
因此,我选择覆盖 class setUp()
,如下所述:https://developer.apple.com/reference/xctest/xctestcase
这很好,但是现在,我不能再使用标准了waitForExpectations
。 (在 class override setUp())
中,我收到几个编译器错误,告诉我我不再调用相同的 waitForExpectations
因为我在 class 方法中,而不是测试用例。
为了解决这个问题,我想像这样使用信号量:
class ServiceLayerTests: XCTestCase {
static var apiService: APIService = APIService()
let sessionManager = SessionManager(serverTrustPolicyManager: ServerTrustPolicyManager(policies: ["http://localhost:3000/": .disableEvaluation]))
static var companyManger: UserWebResource?
static var companyManagerID = -1
override class func setUp() {
apiService.baseURL = "http://localhost:3000/"
beginIntegrationTests()
}
class func beginIntegrationTests() {
var semaphore = DispatchSemaphore(value: 0)
apiService.beginIntegrationTests(completion: {resource, error in
if let resource = resource {
if let manager = resource as? UserWebResource {
companyManger = manager
companyManagerID = manager.id
semaphore.signal()
}
}
})
_ = semaphore.wait(timeout: DispatchTime.distantFuture)
}
}
这不起作用。在引擎盖下,有一个对服务器的 alamo fire 调用,它响应用户以用于集成测试。我确实看到服务器在旋转,所以我知道实际的通信正在进行,但我从未进入完成关闭。
我怀疑我不明白 Swift 是如何处理信号量的,而且我不知何故造成了死锁。如果有人有更好的解决方案,我将非常乐意听到。
I get several compiler errors that tell me that I am no longer calling the same
waitForExpectations
because I am in a class method, not a test case
有道理。您可能想要的是重构,以便您处于测试用例中:
override class func setUp() {
apiService.baseURL = "http://localhost:3000/"
}
func testIntegrationTests() {
let urlExpectation = expectation(description: "INTEGRATION TEST")
apiService.beginIntegrationTests(completion: {resource, error in
// ...
urlExpectation.fulfill()
})
// not sure what an acceptable timeout would be, I chose this at random
waitForExpectations(timeout: 25) { error in
if let error = error {
print("Error: \(error.localizedDescription)")
}
}
}
可以在这里找到包含一些好的测试示例的最佳资源之一:http://nshipster.com/xctestcase/
您可以将期望创建为执行一次性设置并在完成时执行的惰性变量。
在每次测试 setUp()
函数开始时,您可以等待该期望。
None 的测试将 运行 直到完成,并且初始设置将 运行 只有一次。
class WaitForSetup_Tests: XCTestCase {
lazy var initialSetupFinished: XCTestExpectation = {
let initialSetupFinished = expectation(description: "initial setup finished")
initialSetupTask() { // your setup task that executes this closure on completion
initialSetupFinished.fulfill()
return
}
return initialSetupFinished
}()
override func setUp() {
wait(for: [initialSignOutFinished], timeout: 2.0)
// do your per-test setup here
}
}
注意:此解决方案避免使用 override class function setUp()
class 方法,因为除了在实例中,我不知道如何使用期望。