> Что проверяют юнит тесты (iOS, Swift)
Уровень: senior · Роль: qa · Категория: Технические вопросы
Компании: ЦРТ, Тинькофф, ЛИПТ Софт
Стек: iOS, Swift
> Пример ответа
Короткий ответ
Юнит тесты проверяют поведение отдельной единицы кода - функции, метода, структуры или класса - в изоляции от остальной системы. Они валидируют корректность логики, обработку граничных случаев, возвращаемые значения и взаимодействие с зависимостями через моки и стабы. Основная цель - быстро подтвердить, что конкретный модуль работает согласно спецификации, и поймать регрессии при изменениях.
Подробное объяснение
Юнит тесты фокусируются на трёх аспектах:
-
Функциональная корректность - возвращает ли метод ожидаемый результат для заданных входных данных. Это включает happy path, ошибки, пустые значения, крайние случаи (границы диапазонов, nil, пустые коллекции).
-
Инварианты и контракты - сохраняются ли постусловия: состояние объекта после вызова, неизменяемость данных, корректность типов, отсутствие побочных эффектов за пределами модуля.
-
Взаимодействие с зависимостями - правильные ли вызовы делает модуль: порядок, аргументы, количество обращений. Для этого используют моки, стабы и шпионы, чтобы изолировать тестируемый код от сети, базы данных, файловой системы и других модулей.
В iOS/Swift юнит тесты дополнительно проверяют:
- управление памятью (отсутствие retain cycles через weak ссылки);
- thread safety (если модуль работает с конкурентностью);
- корректность работы с опциональными значениями и force unwrap;
- соблюдение протоколов и делегирования.
Важно: юнит тесты не проверяют интеграцию между модулями, UI, производительность в реальных условиях или поведение приложения в целом - это зона интеграционных и UI тестов.
На практике
Для senior QA в iOS контексте важно понимать, что юнит тесты - это не просто проверка "функция вернула true". На практике проверяют:
- Бизнес-логику - расчёты, валидацию, преобразования данных. Например, тест для модели корзины: добавление товара, изменение количества, расчёт суммы со скидкой.
- Сетевой слой - через протокол URLProtocol или мок URLSession проверяют декодирование ответов, обработку ошибок, retry логику.
- Хранилище - Core Data, UserDefaults, Keychain: сохранение, чтение, миграции, обработка повреждённых данных.
- Вспомогательные утилиты - форматирование дат, парсинг строк, валидация email, работа с опциональными значениями.
- Реактивные цепочки - если используется Combine или RxSwift: проверка последовательности событий, ошибок, отмены подписки.
Типичный подход - AAA (Arrange, Act, Assert): подготовить данные, выполнить действие, проверить результат. Для изоляции используют dependency injection: тестируемый объект получает мок через инициализатор или свойство.
Пример кода
SWIFTimport XCTestfinal class CartTests: XCTestCase {func testAddItemUpdatesTotalPrice() {// Arrangelet cart = Cart()let item = Item(id: 1, name: "Book", price: 100)// Actcart.add(item)// AssertXCTAssertEqual(cart.totalPrice, 100)XCTAssertEqual(cart.itemsCount, 1)}func testApplyDiscountDoesNotExceedZero() {// Arrangelet cart = Cart()cart.add(Item(id: 1, name: "Book", price: 50))// Actcart.applyDiscount(80) // 80% скидка// AssertXCTAssertEqual(cart.totalPrice, 10)}func testRemoveItemDecrementsCount() {// Arrangelet cart = Cart()let item = Item(id: 1, name: "Book", price: 100)cart.add(item)// Actcart.remove(item)// AssertXCTAssertEqual(cart.itemsCount, 0)XCTAssertEqual(cart.totalPrice, 0)}}
Как отвечать на собеседовании
Начните с чёткого определения: юнит тест проверяет одну единицу кода в изоляции. Затем перечислите, что именно проверяется: входные-выходные данные, граничные случаи, обработку ошибок, взаимодействие с зависимостями. Упомяните, что в Swift для этого используются XCTest и моки через протоколы или DI.
Приведите конкретный пример из практики: как вы тестировали сетевой слой или бизнес-логику. Покажите, что понимаете разницу между юнит, интеграционными и UI тестами. Подчеркните важность тестирования негативных сценариев и краевых случаев - это отличает senior от junior.
Если спросят про покрытие - скажите, что 100% покрытие не самоцель, важнее тестировать критичную логику и частые пути изменения кода. Упомяните, что юнит тесты должны быть быстрыми, детерминированными и не зависеть от внешних ресурсов.
Что проверяет интервьюер
Интервьюер оценивает:
- Понимание границ юнит тестирования - что входит, а что нет.
- Умение изолировать зависимости через моки, стабы, DI.
- Знание типичных сценариев для iOS: работа с URLSession, Core Data, Combine.
- Способность проектировать тесты: какие кейсы покрывать, как называть тесты, как структурировать.
- Понимание trade-off: скорость vs глубина, изоляция vs реалистичность.
- Практический опыт: как вы решали проблемы с флаки-тестами, асинхронностью, глобальным состоянием.
Senior должен показать, что тесты - это инструмент дизайна: они заставляют писать более модульный, тестируемый код. Также важно умение объяснить, когда юнит тесты неэффективны и нужны другие уровни.
Типичные ошибки
- Тестирование реализации, а не поведения - проверка внутренних вызовов вместо результата. Это делает тесты хрупкими.
- Отсутствие изоляции - тест обращается к реальной сети, базе данных или файловой системе. Такой тест медленный и недетерминированный.
- Тестирование только happy path - пропуск обработки ошибок, пустых значений, границ диапазонов.
- Слишком много моков - тест превращается в проверку того, что мок вызван, а не того, что логика корректна.
- Игнорирование асинхронности - тест завершается до завершения асинхронной операции, либо использует sleep вместо ожидания через expectation.
- Тестирование фреймворка - например, проверка того, что URLSession возвращает данные. Это не ваша логика.
- Слишком крупные юнит тесты - проверка целого сценария с несколькими модулями - это уже интеграционный тест.
- Пренебрежение тестами для легаси-кода - если код не тестируемый, сначала рефакторят, а не пишут тесты "как есть".
> Похожие задачи по qa
По какой методологии работаете
В чем разница тестирования iOS и Android?
Как смотреть логи мобильного приложения и какими способами?
Как работать с JSON в автотестах
> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?
Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью