Как покрывать бизнес-логику тестами
Что проверяют
Умеете ли вы писать код так, чтобы бизнес-логику можно было проверить без симулятора, сети и интерфейса. Демо-тест на сложение двух чисел интервьюеру неинтересен: ему важно, где у вас живёт логика и как вы подменяете зависимости. Следом обычно спрашивают про асинхронный код и про то, какой процент покрытия вы считаете нормальным.
Как отвечать
- логика вне экрана: правила расчёта, валидации, переходы состояний живут в отдельных типах (сервисы, use case, Interactor во VIPER, view model), а не в
UIViewControllerили телеView. Такие типы проверяются обычными юнит-тестами за миллисекунды; - зависимости через протоколы: сеть, хранилище, текущее время,
UserDefaultsпередаются через инициализатор. В тесте подставляются двойники: stub возвращает заготовленный ответ, spy запоминает вызовы, fake это упрощённая реализация, например хранилище в памяти. Рантайм-моков уровня Mockito в Swift практически нет, поэтому двойники пишут руками или генерируют (Mockolo, Sourcery); - фреймворки: XCTest и Swift Testing, который появился в Xcode 16:
@Test,#expect,#require, параметризованные тесты черезarguments:. Оба можно держать в одном таргете; - асинхронность: тестовые функции объявляются
async, для колбэков в XCTest естьXCTestExpectationиawait fulfillment(of:timeout:). Время и задержки подменяются, а не пережидаются черезsleep; - что покрывать: граничные значения, ошибки зависимостей, недопустимые переходы состояний, округления в деньгах. Пирамида: много юнит-тестов, меньше интеграционных, UI-тесты только на критичные сценарии;
- CI: тесты запускаются на каждый PR через
xcodebuild testили Fastlane. Покрытие собирается в Xcode, но цифра служит подсказкой, а не целью.
Где спотыкаются
Проверяют логику через UI-тесты. Они медленные, нестабильные и при падении не говорят, какое правило сломалось.
Обращаются к URLSession.shared и синглтонам прямо из логики. Без подмены зависимостей тест ходит в сеть и падает от любого сбоя на стороне сервера.
Гонятся за процентом покрытия и пишут тесты на геттеры. Покрытие растёт, а сложные ветки с ошибками и крайними случаями так и остаются непроверенными.