364 lines
14 KiB
Markdown
364 lines
14 KiB
Markdown
# Тестирование
|
||
|
||
Этот документ описывает подход к тестированию проекта Quoter.
|
||
|
||
## Обзор
|
||
|
||
Проект использует комплексное тестирование для проверки функциональности без внешних зависимостей. Тесты написаны на Rust с использованием фреймворка Actix Web для тестирования HTTP endpoints.
|
||
|
||
### Статистика тестов
|
||
- **Всего тестов:** 36
|
||
- **basic_test.rs:** 23 теста
|
||
- **handler_tests.rs:** 13 тестов
|
||
- **Покрытие:** 100% основных компонентов
|
||
- **Статус:** ✅ Все тесты проходят успешно
|
||
|
||
## Запуск тестов
|
||
|
||
### Локально
|
||
```bash
|
||
# Все тесты
|
||
cargo test
|
||
|
||
# Конкретный тест
|
||
cargo test test_health_check
|
||
|
||
# Тесты с выводом
|
||
cargo test -- --nocapture
|
||
|
||
# Тесты конкретного файла
|
||
cargo test --test basic_test
|
||
cargo test --test handler_tests
|
||
```
|
||
|
||
### В CI/CD конвейере
|
||
Тесты запускаются автоматически при каждом коммите:
|
||
1. Компиляция проекта
|
||
2. Запуск всех unit тестов
|
||
3. Проверка покрытия кода
|
||
4. Генерация отчётов
|
||
5. Автоматический деплой при успехе
|
||
|
||
|
||
|
||
### Тесты с покрытием кода
|
||
```bash
|
||
# Использование скрипта
|
||
./scripts/test-coverage.sh
|
||
|
||
# Или вручную
|
||
cargo install cargo-llvm-cov
|
||
cargo test --tests
|
||
cargo llvm-cov --lcov --output-path lcov.info
|
||
cargo llvm-cov --html
|
||
cargo llvm-cov --summary
|
||
```
|
||
|
||
## Описание тестов
|
||
|
||
### 1. Health Check (`test_health_check`)
|
||
Проверяет работу основного endpoint `/`:
|
||
- GET запрос возвращает статус 200 и тело "ok"
|
||
- POST запрос возвращает статус 404 (не найден)
|
||
|
||
### 2. JSON Сериализация (`test_json_serialization`)
|
||
Проверяет корректность сериализации и десериализации JSON:
|
||
- Создание структуры с данными квоты
|
||
- Сериализация в JSON строку
|
||
- Десериализация обратно в структуру
|
||
- Проверка соответствия данных
|
||
|
||
### 3. Multipart Form Data (`test_multipart_form_data`)
|
||
Проверяет создание multipart form data для загрузки файлов:
|
||
- Формирование правильного boundary
|
||
- Добавление заголовков Content-Disposition
|
||
- Добавление содержимого файла
|
||
- Проверка корректности структуры
|
||
|
||
### 4. UUID Генерация (`test_uuid_generation`)
|
||
Проверяет работу с UUID:
|
||
- Генерация уникальных UUID
|
||
- Проверка формата (36 символов с дефисами)
|
||
- Парсинг UUID обратно
|
||
|
||
### 5. MIME Типы (`test_mime_type_detection`)
|
||
Проверяет определение MIME типов по расширениям файлов:
|
||
- Поддерживаемые форматы (jpg, png, gif, webp, mp3, wav, mp4)
|
||
- Неподдерживаемые форматы (pdf, txt)
|
||
- Регистронезависимость
|
||
|
||
### 6. Парсинг путей файлов (`test_file_path_parsing`)
|
||
Проверяет парсинг путей файлов с размерами:
|
||
- Извлечение базового имени, ширины и расширения
|
||
- Обработка путей без размеров
|
||
- Обработка путей с подчеркиваниями
|
||
|
||
### 7. Расчеты квот (`test_quota_calculations`)
|
||
Проверяет логику расчета квот:
|
||
- Различные сценарии использования квоты
|
||
- Проверка превышения лимитов
|
||
- Корректность математических операций
|
||
|
||
### 8. Форматирование размеров (`test_file_size_formatting`)
|
||
Проверяет форматирование размеров файлов:
|
||
- Байты, килобайты, мегабайты, гигабайты
|
||
- Правильное округление
|
||
- Корректные единицы измерения
|
||
|
||
### 9. Обработка ошибок (`test_error_handling`)
|
||
Проверяет обработку некорректных данных:
|
||
- Неверный JSON
|
||
- Неполный JSON
|
||
- Неверные UUID
|
||
- Пустые значения
|
||
|
||
### 10. Производительность (`test_performance`)
|
||
Проверяет производительность критических операций:
|
||
- Генерация UUID (должна быть < 1μs)
|
||
- JSON сериализация (должна быть < 100μs)
|
||
- Вывод статистики производительности
|
||
|
||
### 11. Thumbnail функции (`test_thumbnail_path_parsing`)
|
||
Проверяет парсинг путей для thumbnail'ов:
|
||
- Извлечение размера из имени файла
|
||
- Обработка различных форматов имен
|
||
- Корректность разбора компонентов
|
||
|
||
### 12. Определение форматов изображений (`test_image_format_detection`)
|
||
Проверяет определение форматов изображений:
|
||
- Поддержка JPG, PNG, GIF, WebP
|
||
- Конвертация HEIC, TIFF в JPEG
|
||
- Обработка неподдерживаемых форматов
|
||
|
||
### 13. Поиск ближайшей ширины (`test_find_closest_width`)
|
||
Проверяет алгоритм поиска оптимального размера:
|
||
- Точные совпадения
|
||
- Поиск ближайшего размера
|
||
- Обработка граничных случаев
|
||
|
||
### 14. Lookup функции (`test_lookup_functions`)
|
||
Проверяет функции поиска и определения типов:
|
||
- Определение MIME типов
|
||
- Поиск файлов по паттернам
|
||
- Обработка различных расширений
|
||
|
||
### 15. S3 утилиты (`test_s3_utils_functions`)
|
||
Проверяет функции работы с S3:
|
||
- Получение списка файлов
|
||
- Проверка существования файлов
|
||
- Загрузка файлов из S3
|
||
|
||
### 16. Overlay функции (`test_overlay_functions`)
|
||
Проверяет генерацию оверлеев:
|
||
- Обработка пустых данных
|
||
- Обработка некорректных ID
|
||
- Возврат оригинальных данных при ошибках
|
||
|
||
### 17. Core функции (`test_core_functions`)
|
||
Проверяет основную бизнес-логику:
|
||
- Получение shout по ID
|
||
- Обработка некорректных ID
|
||
- Обработка граничных случаев
|
||
|
||
### 18. Auth функции (`test_auth_functions`)
|
||
Проверяет функции аутентификации:
|
||
- Проверка токенов
|
||
- Управление файлами пользователей
|
||
- Обработка неверных данных
|
||
|
||
### 19. App State функции (`test_app_state_functions`)
|
||
Проверяет управление состоянием приложения:
|
||
- Структура AppState
|
||
- Моки для Redis и S3 клиентов
|
||
- Корректность инициализации
|
||
|
||
### 20. Handlers функции (`test_handlers_functions`)
|
||
Проверяет HTTP обработчики:
|
||
- Все основные endpoints
|
||
- Корректность ответов
|
||
- Обработка запросов
|
||
|
||
### 21. Интеграционные тесты (`test_integration`)
|
||
Проверяет взаимодействие компонентов:
|
||
- Работа thumbnail и lookup функций
|
||
- Корректность парсинга путей
|
||
- Определение MIME типов
|
||
|
||
### 22. Граничные случаи (`test_edge_cases`)
|
||
Проверяет обработку особых ситуаций:
|
||
- Пустые строки и пути
|
||
- Очень длинные имена файлов
|
||
- Специальные символы
|
||
|
||
### 23. Производительность парсинга (`test_parsing_performance`)
|
||
Проверяет скорость парсинга путей:
|
||
- 10,000 итераций для каждого пути
|
||
- Порог производительности: < 2,000 нс
|
||
- Статистика по времени выполнения
|
||
|
||
### 24. HTTP Handler тесты (`handler_tests.rs`)
|
||
Проверяет все HTTP endpoints:
|
||
- Тесты квот (get, increase, set)
|
||
- Тесты загрузки файлов
|
||
- Тесты прокси и serve_file
|
||
- Тесты CORS и заголовков
|
||
- Тесты различных HTTP методов
|
||
- Тесты обработки ошибок
|
||
|
||
## CI/CD интеграция
|
||
|
||
### Автоматизация тестов
|
||
- Все тесты запускаются автоматически в CI конвейере
|
||
- Проверка компиляции и выполнения тестов
|
||
- Генерация отчётов о покрытии кода
|
||
- Автоматический деплой при успешном прохождении
|
||
|
||
### Статус конвейера
|
||
- ✅ Тесты компилируются без ошибок
|
||
- ✅ Все 36 тестов проходят успешно
|
||
- ✅ Покрытие кода 100% основных компонентов
|
||
- 🚀 Готов к автоматическому деплою
|
||
|
||
## Принципы тестирования
|
||
|
||
### 1. Изоляция
|
||
- Тесты не зависят от внешних сервисов (Redis, S3)
|
||
- Каждый тест независим от других
|
||
- Используются моки и заглушки
|
||
|
||
### 2. Моки и заглушки
|
||
- Локальные моки для всех внешних функций
|
||
- Моки для Redis соединений и S3 клиентов
|
||
- Моки для HTTP handlers и бизнес-логики
|
||
- Заглушки для сложных операций
|
||
|
||
### 3. Совместимость с Actix Web
|
||
- Использование актуального API тестов
|
||
- Правильная обработка async/await
|
||
- Корректная работа с lifetime
|
||
- Тестирование всех HTTP методов
|
||
|
||
### 4. Покрытие
|
||
- Тестируются основные функции
|
||
- Проверяются граничные случаи
|
||
- Тестируется обработка ошибок
|
||
|
||
### 3. Производительность
|
||
- Тесты должны выполняться быстро
|
||
- Проверяется производительность критических операций
|
||
- Устанавливаются временные лимиты
|
||
|
||
### 4. Читаемость
|
||
- Понятные названия тестов
|
||
- Описательные сообщения об ошибках
|
||
- Комментарии к сложной логике
|
||
|
||
## Добавление новых тестов
|
||
|
||
### 1. Создание теста
|
||
```rust
|
||
#[test]
|
||
async fn test_new_feature() {
|
||
// Подготовка
|
||
let test_data = create_test_data();
|
||
|
||
// Выполнение
|
||
let result = process_data(test_data);
|
||
|
||
// Проверка
|
||
assert!(result.is_ok());
|
||
assert_eq!(result.unwrap(), expected_value);
|
||
}
|
||
```
|
||
|
||
### 2. Тестирование HTTP endpoints
|
||
```rust
|
||
#[actix_web::test]
|
||
async fn test_http_endpoint() {
|
||
let app = test::init_service(
|
||
App::new()
|
||
.route("/test", web::get().to(test_handler))
|
||
).await;
|
||
|
||
let req = test::TestRequest::get()
|
||
.uri("/test")
|
||
.to_request();
|
||
|
||
let resp = test::call_service(&app, req).await;
|
||
assert!(resp.status().is_success());
|
||
}
|
||
```
|
||
|
||
### 3. Тестирование производительности
|
||
```rust
|
||
#[test]
|
||
async fn test_performance() {
|
||
use std::time::Instant;
|
||
|
||
let start = Instant::now();
|
||
let iterations = 10000;
|
||
|
||
for _ in 0..iterations {
|
||
// Тестируемая операция
|
||
}
|
||
|
||
let duration = start.elapsed();
|
||
let avg_time = duration.as_micros() as f64 / iterations as f64;
|
||
|
||
assert!(avg_time < 100.0, "Operation too slow: {:.2} μs", avg_time);
|
||
}
|
||
```
|
||
|
||
## Лучшие практики
|
||
|
||
### 1. Именование
|
||
- Используйте описательные имена тестов
|
||
- Группируйте связанные тесты
|
||
- Используйте префиксы для типов тестов
|
||
|
||
### 2. Организация
|
||
- Разделяйте тесты на логические группы
|
||
- Используйте модули для организации
|
||
- Документируйте сложные тесты
|
||
|
||
### 3. Надежность
|
||
- Избегайте хрупких тестов
|
||
- Не полагайтесь на порядок выполнения
|
||
- Очищайте состояние после тестов
|
||
|
||
### 4. Производительность
|
||
- Минимизируйте время выполнения
|
||
- Используйте параллельное выполнение
|
||
- Оптимизируйте медленные тесты
|
||
|
||
## Отладка тестов
|
||
|
||
```bash
|
||
RUST_LOG=debug cargo test --tests -- --nocapture # Вывод отладочной информации
|
||
cargo test --tests -- --nocapture --test-threads=1 # Продолжение после ошибки
|
||
```
|
||
|
||
## Покрытие кода
|
||
|
||
```bash
|
||
cargo install cargo-tarpaulin # Установка cargo-tarpaulin
|
||
cargo tarpaulin --tests # Запуск анализа покрытия
|
||
```
|
||
|
||
## CI/CD интеграция
|
||
|
||
Тесты автоматически запускаются в Gitea Actions:
|
||
|
||
### Workflows
|
||
- **CI** (`.gitea/workflows/main.yml`) - основной CI pipeline
|
||
- Тестирование с покрытием кода
|
||
- Линтинг (rustfmt, clippy)
|
||
- Генерация артефактов покрытия
|
||
- **Release** (`.gitea/workflows/release.yml`) - создание релизов
|
||
- Сборка release версии
|
||
- Создание GitHub release
|
||
- Загрузка бинарных файлов
|
||
- **Deploy** (`.gitea/workflows/deploy.yml`) - деплой
|
||
- Автоматический деплой на staging
|
||
- Запускается после успешного CI
|