Правила написания unit-тестов
Для запуска тестов используй только команду make test.
Когда применять
- •При написании новых unit-тестов для iOS-проекта
- •При рефакторинге существующих тестов для соответствия стандартам
- •При тестировании бизнес-логики сервисов и ViewModels
- •При создании мок-клиентов для тестирования интеграции с сервером
- •При написании параметризированных тестов для множества сценариев
Основные принципы
1. Технологии тестирования
- •Swift Testing (import Testing) - основной фреймворк
- •@Test для тестовых функций
- •#expect для проверок
- •#require для разворачивания опционалов
2. Правила написания тестов
Синтаксис тестов
См. примеры синтаксиса в references/EXAMPLE.md.
Описания тестов
- •Обязательно добавляй описание теста на русском языке в аннотации
@Test - •Используй краткие и понятные описания того, что тестируется
- •Пример:
@Test("Должен возвращать правильный результат для валидных данных")
Работа с опционалами
- •Всегда разворачивай опционалы перед проверками с помощью
try #require() - •Не используй знаки вопроса (?) в проверках
#expect - •Пример:
let value = try #require(optionalValue)затем#expect(value == expected)
Асинхронные тесты
- •Добавляй
throwsесли в тесте естьtry - •Не добавляй
throwsесли нетtryв тесте - •Добавляй
asyncдля асинхронных тестов - •Не добавляй
asyncесли в тесте нет await
Проверки Bool условий
- •Не используй равенство для Bool значений
- •Используй прямое сравнение:
#expect(isTrue)или#expect(isFalse) - •Пример:
#expect(condition)вместо#expect(condition == true)
Проверка конкретных ошибок
- •Используй
#expect(throws: ErrorType)для проверки конкретных типов ошибок - •Не используй do-catch блоки для проверки ожидаемых ошибок
См. примеры в references/EXAMPLE.md.
Параметризированные тесты
- •Используй параметризированные тесты когда нужно протестировать несколько сценариев с разными аргументами и одинаковой логикой
- •Добавляй
arguments:в аннотацию@Testс массивом значений - •Параметр функции должен соответствовать типу аргументов
- •Не используй в аргументах ожидаемый результат - в аргументах должны быть только вводные данные
- •Группируй тесты с одинаковым сценарием или ожидаемым результатом
- •Преимущества: сокращает дублирование кода, делает тесты более читаемыми, легко добавлять новые сценарии
См. примеры в references/EXAMPLE.md.
Комментарии в тестах
- •Лишние комментарии в тестах не нужны - код должен быть самодокументируемым
- •Для простых сценариев комментарии не нужны вообще
- •Для сложной логики можно добавить краткий комментарий внутри
#expect - •Не используй обычные комментарии (
//) над#expect - •Чем короче комментарий, тем лучше
См. примеры в references/EXAMPLE.md.
3. Структура тестов
- •Один тестовый файл на модуль
- •Тестировать бизнес-логику в сервисах
- •Тестировать ViewModels с моками
- •Не тестировать UI напрямую
- •Не дублировать одинаковые сценарии в разных тестах
- •Пиши простые тесты, в тестах не должно быть сложной логики и проверки разных сценариев типа "if shouldThrow {} else {}"
4. Тестирование интеграции с сервером
- •Используй только мок-клиенты для тестирования запросов к серверу и для работы со Swift Data (ModelContainer)
- •Никогда не отправляй реальные запросы на сервер в тестах
- •Создавай общие мок-клиенты в папке с тестами для переиспользования в разных тестовых файлах
- •Группируй мок-клиенты по функциональности (например,
MockProgressClient,MockAuthClient) - •Используй dependency injection для передачи мок-клиентов в тестируемые сервисы
Заключение
При написании unit-тестов всегда следуй этим правилам для обеспечения консистентности и правильности тестового кода в проекте.