XCTAssert의 비동기 Assertion (XCTAssertEventually) 만들어 보았습니다.
소개
안녕하세요.
갑작스럽지만 iOS의 유닛 테스트에서 XCTest를 사용하여 비동기 테스트를 작성하는 것은 상당히 귀찮습니다.
최근 여러가지로 Quick/Nimble에서 XCTest로 되돌렸습니다만, Nimble에 있던 toEventually가 상당히 매력으로, XCTest에서 XCTExpectation이나 wait(for: [expectation], timeout: 1.0)라든지 매번 쓰는 귀찮다고 생각해 있었습니다.
그래서 XCTest에서도 Nimble의 toEventually와 같이 간단하게 비동기의 Assertion이 쓸 수 있는 Extension을 만들어 보았습니다.
XCTestExtensions
htps : // 기주 b. 코 m / 신주 / XC에서 x x 신시온 s
사용법
비동기 처리의 값을 확인하는 예입니다.
func test_XCTAssertTrueEventually() {
var value = false
DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
value = true
}
XCTAssertTrueEventually(value) // success
}
UI 관련 테스트에 적용한 예.
(ViewControllerA 버튼을 탭하면 ViewControllerB가 표시됩니다)
func test_tappedButton() {
var viewControllerA = ViewControllerA()
viewControllerA.button.sendActions(for: .touchUpInside)
XCTAssertTrueEventually(viewControllerA.presentedViewController is ViewControllerB) // success
}
구현
public func XCTAssertTrueEventually(_ expression: @escaping @autoclosure () throws -> Bool, timeout: TimeInterval = 1.0, pollInterval: TimeInterval = 0.1, file: StaticString = #file, line: UInt = #line) {
let expectation = XCTestExpectation()
for i in 0..<Int(timeout/pollInterval) {
DispatchQueue.main.asyncAfter(deadline: .now() + pollInterval * Double(i)) {
if (try! expression()) {
expectation.fulfill()
}
}
}
switchProcess(
by: XCTWaiter.wait(for: [expectation], timeout: timeout),
timedOutMessage: "XCTAssertNotNilEventually failed",
file: file,
line: line
)
}
private func switchProcess(by result: XCTWaiter.Result, timedOutMessage: String, file: StaticString = #file, line: UInt = #line) {
switch result {
case .completed:
break
case .timedOut:
XCTFail(timedOutMessage, file: file, line: line)
default:
XCTFail("resultに応じたmessageをいれると良い", file: file, line: line)
}
}
간단한 해설
구현 자체는 XCTestExpectation과 XCTWaiter를 사용한 비동기 처리에 DispatchQueue의 asyncAfter를 결합한 것입니다.
timeout과 pollInterval을 바탕으로 일정 간격으로 expression을 실행한 결과에서 fulfill()이 실행되어 XCTWaiter.wait에서 얻을 수 있는 값으로부터 최종적인 처리가 정해지게 되어 있습니다.
timeout과 pollInterval은 호출시 설정할 수 있으므로 테스트별로 조정할 수도 있습니다.
인터페이스는 XCTAssert를 참고하면서 기존 메서드를 사용할 때 알 수 있도록 끝에 Eventually를 붙이게 했습니다.
단지 wrapper라고 하면 그렇습니다만, 사용할 때 매번 작법과 같이 XCTestExpectation등의 코드를 쓰지 않아도 좋아지기 때문에 마음에 듭니다.
마지막으로
덧붙여서 이번에 쓴 코드는, 회사에서 「평소의 안건 업무와 직접 관계없는 일 합시다~」라고 하는 날이 있었으므로 생각나서 쓴 코드입니다.
그런 다음 몇 가지 종류의 Assertion을 함께 OSS로 공개했습니다.
좋으면 사용해보고 스타와 PullRequest를 기다리고 있습니다 mm
Reference
이 문제에 관하여(XCTAssert의 비동기 Assertion (XCTAssertEventually) 만들어 보았습니다.), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/shindyu/items/b16b8de3f6c08cb7843c
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
비동기 처리의 값을 확인하는 예입니다.
func test_XCTAssertTrueEventually() {
var value = false
DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
value = true
}
XCTAssertTrueEventually(value) // success
}
UI 관련 테스트에 적용한 예.
(ViewControllerA 버튼을 탭하면 ViewControllerB가 표시됩니다)
func test_tappedButton() {
var viewControllerA = ViewControllerA()
viewControllerA.button.sendActions(for: .touchUpInside)
XCTAssertTrueEventually(viewControllerA.presentedViewController is ViewControllerB) // success
}
구현
public func XCTAssertTrueEventually(_ expression: @escaping @autoclosure () throws -> Bool, timeout: TimeInterval = 1.0, pollInterval: TimeInterval = 0.1, file: StaticString = #file, line: UInt = #line) {
let expectation = XCTestExpectation()
for i in 0..<Int(timeout/pollInterval) {
DispatchQueue.main.asyncAfter(deadline: .now() + pollInterval * Double(i)) {
if (try! expression()) {
expectation.fulfill()
}
}
}
switchProcess(
by: XCTWaiter.wait(for: [expectation], timeout: timeout),
timedOutMessage: "XCTAssertNotNilEventually failed",
file: file,
line: line
)
}
private func switchProcess(by result: XCTWaiter.Result, timedOutMessage: String, file: StaticString = #file, line: UInt = #line) {
switch result {
case .completed:
break
case .timedOut:
XCTFail(timedOutMessage, file: file, line: line)
default:
XCTFail("resultに応じたmessageをいれると良い", file: file, line: line)
}
}
간단한 해설
구현 자체는 XCTestExpectation과 XCTWaiter를 사용한 비동기 처리에 DispatchQueue의 asyncAfter를 결합한 것입니다.
timeout과 pollInterval을 바탕으로 일정 간격으로 expression을 실행한 결과에서 fulfill()이 실행되어 XCTWaiter.wait에서 얻을 수 있는 값으로부터 최종적인 처리가 정해지게 되어 있습니다.
timeout과 pollInterval은 호출시 설정할 수 있으므로 테스트별로 조정할 수도 있습니다.
인터페이스는 XCTAssert를 참고하면서 기존 메서드를 사용할 때 알 수 있도록 끝에 Eventually를 붙이게 했습니다.
단지 wrapper라고 하면 그렇습니다만, 사용할 때 매번 작법과 같이 XCTestExpectation등의 코드를 쓰지 않아도 좋아지기 때문에 마음에 듭니다.
마지막으로
덧붙여서 이번에 쓴 코드는, 회사에서 「평소의 안건 업무와 직접 관계없는 일 합시다~」라고 하는 날이 있었으므로 생각나서 쓴 코드입니다.
그런 다음 몇 가지 종류의 Assertion을 함께 OSS로 공개했습니다.
좋으면 사용해보고 스타와 PullRequest를 기다리고 있습니다 mm
Reference
이 문제에 관하여(XCTAssert의 비동기 Assertion (XCTAssertEventually) 만들어 보았습니다.), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/shindyu/items/b16b8de3f6c08cb7843c
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
public func XCTAssertTrueEventually(_ expression: @escaping @autoclosure () throws -> Bool, timeout: TimeInterval = 1.0, pollInterval: TimeInterval = 0.1, file: StaticString = #file, line: UInt = #line) {
let expectation = XCTestExpectation()
for i in 0..<Int(timeout/pollInterval) {
DispatchQueue.main.asyncAfter(deadline: .now() + pollInterval * Double(i)) {
if (try! expression()) {
expectation.fulfill()
}
}
}
switchProcess(
by: XCTWaiter.wait(for: [expectation], timeout: timeout),
timedOutMessage: "XCTAssertNotNilEventually failed",
file: file,
line: line
)
}
private func switchProcess(by result: XCTWaiter.Result, timedOutMessage: String, file: StaticString = #file, line: UInt = #line) {
switch result {
case .completed:
break
case .timedOut:
XCTFail(timedOutMessage, file: file, line: line)
default:
XCTFail("resultに応じたmessageをいれると良い", file: file, line: line)
}
}
구현 자체는 XCTestExpectation과 XCTWaiter를 사용한 비동기 처리에 DispatchQueue의 asyncAfter를 결합한 것입니다.
timeout과 pollInterval을 바탕으로 일정 간격으로 expression을 실행한 결과에서 fulfill()이 실행되어 XCTWaiter.wait에서 얻을 수 있는 값으로부터 최종적인 처리가 정해지게 되어 있습니다.
timeout과 pollInterval은 호출시 설정할 수 있으므로 테스트별로 조정할 수도 있습니다.
인터페이스는 XCTAssert를 참고하면서 기존 메서드를 사용할 때 알 수 있도록 끝에 Eventually를 붙이게 했습니다.
단지 wrapper라고 하면 그렇습니다만, 사용할 때 매번 작법과 같이 XCTestExpectation등의 코드를 쓰지 않아도 좋아지기 때문에 마음에 듭니다.
마지막으로
덧붙여서 이번에 쓴 코드는, 회사에서 「평소의 안건 업무와 직접 관계없는 일 합시다~」라고 하는 날이 있었으므로 생각나서 쓴 코드입니다.
그런 다음 몇 가지 종류의 Assertion을 함께 OSS로 공개했습니다.
좋으면 사용해보고 스타와 PullRequest를 기다리고 있습니다 mm
Reference
이 문제에 관하여(XCTAssert의 비동기 Assertion (XCTAssertEventually) 만들어 보았습니다.), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/shindyu/items/b16b8de3f6c08cb7843c
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
Reference
이 문제에 관하여(XCTAssert의 비동기 Assertion (XCTAssertEventually) 만들어 보았습니다.), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/shindyu/items/b16b8de3f6c08cb7843c텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)