Ответ
Да, активно использовал XCTest для модульного тестирования (Unit Testing).
Что тестировал:
- Модели данных: Валидация, преобразования форматов, бизнес-правила.
- Бизнес-логика: Сервисы, утилиты, менеджеры.
- ViewModel/Presenter: Проверка корректности выходных состояний на основе входных данных и действий.
Пример теста для валидатора email:
import XCTest
@testable import MyApp
class EmailValidatorTests: XCTestCase {
func testValidEmail() {
let validator = EmailValidator()
XCTAssertTrue(validator.isValid("user@example.com"))
}
func testInvalidEmail() {
let validator = EmailValidator()
XCTAssertFalse(validator.isValid("invalid-email"))
}
func testEmptyEmail() {
let validator = EmailValidator()
XCTAssertFalse(validator.isValid(""))
}
}
Практики:
- Мокирование: Использовал протоколы для создания mock-объектов зависимостей.
- Асинхронность: Применял
XCTestExpectationдля тестирования асинхронного кода. - Покрытие: Стремился к покрытию ключевой логики на уровне 60-80%.
Ответ 18+ 🔞
О, так ты про тесты спрашиваешь? Ну да, я с этим XCTest на короткой ноге, конечно. Без этого сейчас никуда, иначе потом вылезет такое, что волосы дыбом встанут, а виноват будешь ты, потому что не проверил.
Что я там, блядь, мучил:
- Модели данных: Чтобы вся эта валидация и преобразование форматов не выкинули какую-нибудь хуйню в продакшен. Бизнес-правила — святое, их надо гонять по полной.
- Всякая бизнес-логика: Сервисы, утилиты, менеджеры — чтобы работали как швейцарские часы, а не как китайский будильник.
- ViewModel/Presenter: Чтобы на основе одних данных получались правильные состояния, а не пиздец в интерфейсе. Проверял вход, выход и что между ними.
Вот, смотри, как я, например, валидатор почты тестил, чтоб он не пропускал всякую дичь:
import XCTest
@testable import MyApp
class EmailValidatorTests: XCTestCase {
func testValidEmail() {
let validator = EmailValidator()
XCTAssertTrue(validator.isValid("user@example.com"))
}
func testInvalidEmail() {
let validator = EmailValidator()
XCTAssertFalse(validator.isValid("invalid-email"))
}
func testEmptyEmail() {
let validator = EmailValidator()
XCTAssertFalse(validator.isValid(""))
}
}
А как я это делал, внатуре:
- Мокирование, ёпта: Заводил протоколы и подсовывал вместо реальных зависимостей их подставные копии — моки. Чтобы тест гонял только то, что нужно, а не лез в сеть или базу.
- Асинхронщина: Использовал
XCTestExpectation, когда нужно было дождаться, пока вся эта асинхронная хуйня завершится. Иначе тест проскакивает, а ошибка вылезает потом. - Покрытие: Гнался за покрытием ключевой логики где-то на 60-80%. Стопроцентное — это, конечно, ебать какая сказка, но на практике часто овердохуища времени уходит за эти последние проценты. Главное — чтобы ядро было прикрыто, а не какая-нибудь хуйня вроде геттеров.