[swift] 가상 타임과 테스트를 위한 테스트 스케줄러 사용 방법

테스트는 소프트웨어 개발의 중요한 부분입니다. 테스트를 통해 코드의 동작을 검증하고 버그를 찾아내는데 도움이 됩니다. 하지만 일부 테스트는 시간에 따라 결과가 달라지는 경우가 있습니다. 예를 들어, 현재 시간이나 타이머와 관련된 동작을 테스트할 때말입니다. 이러한 시나리오에서 가상 타임과 테스트 스케줄러를 사용하면 테스트를 더욱 견고하게 만들 수 있습니다.

가상 타임

가상 타임(Virtual Time)은 시스템의 현재 시간을 테스트 중에 임의로 설정하는 기능입니다. Swift에서는 XCTest 프레임워크를 통해 가상 타임을 사용할 수 있습니다. 다음은 가상 타임을 설정하는 방법입니다.

import XCTest

class MyDateTests: XCTestCase {
    func testCurrentDate() {
        // 가상 타임 시작
        let virtualTime = VirtualTime()
        virtualTime.start()
        
        // 현재 시간 설정
        virtualTime.setCurrentDate(Date(timeIntervalSinceReferenceDate: 0))
        
        // 테스트할 코드 실행
        
        // 현재 시간 확인
        XCTAssertEqual(Date(), Date(timeIntervalSinceReferenceDate: 0))
        
        // 가상 타임 종료
        virtualTime.stop()
    }
}

위의 코드에서는 virtualTime.start()를 통해 가상 타임을 시작하고, virtualTime.setCurrentDate()를 통해 현재 시간을 설정합니다. 테스트 중에는 설정한 가상 타임의 날짜와 시간이 실제 시스템의 시간으로 간주됩니다.

테스트 스케줄러

테스트 스케줄러(Test Scheduler)는 비동기 동작을 테스트하는 데 사용됩니다. 테스트 중에 비동기 작업이 예상대로 동작하는지 확인할 수 있습니다. Swift에서는 Combine 프레임워크를 통해 테스트 스케줄러를 사용할 수 있습니다. 다음은 테스트 스케줄러를 사용하는 예시입니다.

import XCTest
import Combine

class MyAsyncTests: XCTestCase {

    func testAsyncOperation() {
        let expectation = XCTestExpectation(description: "Async operation")

        let cancellable = Just(1)
            .delay(for: .seconds(1), scheduler: DispatchQueue.main)
            .sink { value in
                // 비동기 작업 완료 후 수행할 코드
                XCTAssertEqual(value, 1)
                expectation.fulfill()
            }

        wait(for: [expectation], timeout: 2)
        cancellable.cancel()
    }
}

위의 코드에서는 XCTestExpectation을 사용하여 비동기 작업이 완료될 때까지 대기합니다. Justsink 연산자를 사용하여 1을 방출하는 비동기 작업을 생성하고, delay를 통해 1초 후에 작업이 완료되도록 설정합니다. sink 클로저에서는 비동기 작업이 예상대로 수행되는지 확인합니다. wait 메서드를 통해 비동기 작업이 완료될 때까지 대기하며, cancellable.cancel()을 통해 작업을 취소합니다.

참고 자료