Ответ
Имею опыт написания модульных тестов с использованием нативного фреймворка 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% покрытия.