Pull to refresh

Написание Unit тестов на Swift для проверки асинхронных задач

Reading time2 min
Views4.2K
Сегодня хочу вам быстренько рассказать как тестировать асинхронный код.

Представьте ситуацию, что вам надо загрузить данные из интернета и проверить все ли работает нормально, либо еще какую-нибудь задачу, которая выполняется асинхронно. И как же его протестировать? Что если попробовать так же как и обычный синхронный код?!

    func testAscynFunction() {
        someAsyncFunction()
    }

    func someAsyncFunction() {
        let bg = DispatchQueue.global(qos: .background)
        bg.asyncAfter(deadline: .now() + 5) {
            XCTAssert(false, "Something went wrong")
        }
    }

Такой тест вернет нам положительный результат, так как метод не будет ждать всех наших асинхронных задач.

Для решения такой проблемы в тестах есть одна замечательная вещь: XCTestExpectation
XCTestExpectation задает то, сколько раз должен выполниться асинхронный метод и только после всех этих выполнений тест окончится и скажет были ли ошибки. Вот пример:

class TestAsyncTests: XCTestCase {
// 1) объявляем  expectation
    var expectation: XCTestExpectation!

    func testWithExpectationExample() {
//2) Инициализируем его 
        expectation = expectation(description: "Testing Async")
//3) задаем то количество раз, сколько должен исполниться метод  expectation.fulfill()
        expectation.expectedFulfillmentCount = 5
        for index in 0...5 {
            someAsyncFunctionWithExpectation(at: index)
        }
//5) Ожидаем пока исполнится нужное количество expectation.fulfill()
// в противном же случае по истечении 60 сек метод сам выдаст ошибку, так как не дождался
        waitForExpectations(timeout: 60) { (error) in
            if let error = error {
                XCTFail("WaitForExpectationsWithTimeout errored: \(error)")
            }
        }
    }

    func someAsyncFunctionWithExpectation(at index: Int) {
        let bg = DispatchQueue.global(qos: .background)
        bg.asyncAfter(deadline: .now() + 5) { [weak self ] in
            XCTAssert(false, "Something went wrong at index \(index)")
//4) Именно его исполнение и подсчитывает expectation.expectedFulfillmentCount
            self?.expectation.fulfill()
        }
    }
}

Надеюсь, кому-нибудь будем полезна данная заметка.
Tags:
Hubs:
+8
Comments0

Articles

Change theme settings