Какой у вас опыт модульного (unit) тестирования в iOS?

«Какой у вас опыт модульного (unit) тестирования в iOS?» — вопрос из категории Тестирование, который задают на 28% собеседований IOS Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Имею опыт написания модульных тестов с использованием нативного фреймворка XCTest.

Что тестирую:

  • Бизнес-логику: Чистые функции, преобразователи данных, валидаторы.
  • Сетевой слой: Мокаю URLSession для тестирования сетевых клиентов.
  • Модели данных: Корректность конформности протоколам (Codable, Equatable).

Пример теста для ViewModel:

import XCTest
@testable import MyApp

class LoginViewModelTests: XCTestCase {

    var viewModel: LoginViewModel!
    var mockAuthService: MockAuthService!

    override func setUp() {
        super.setUp()
        mockAuthService = MockAuthService()
        viewModel = LoginViewModel(authService: mockAuthService)
    }

    func testLoginWithValidCredentials() {
        // Arrange
        let expectation = XCTestExpectation(description: "Login succeeds")
        viewModel.onLoginSuccess = { expectation.fulfill() }

        // Act
        viewModel.email = "test@example.com"
        viewModel.password = "validPass123"
        viewModel.login()

        // Assert
        wait(for: [expectation], timeout: 1.0)
        XCTAssertTrue(mockAuthService.loginWasCalled)
    }
}

Подходы и best practices:

  • Моки через протоколы: Зависимости инжектятся через протоколы, что позволяет легко подменять их мок-реализациями.
  • Тестирование асинхронного кода: Использую XCTestExpectation.
  • Структура теста (AAA): Arrange (подготовка), Act (действие), Assert (проверка).
  • Покрытие: Фокусируюсь на тестировании критической логики и сложных сценариев, а не на достижении 100% покрытия.