14 KiB
Тестирование
Этот документ описывает подход к тестированию проекта Quoter.
Обзор
Проект использует комплексное тестирование для проверки функциональности без внешних зависимостей. Тесты написаны на Rust с использованием фреймворка Actix Web для тестирования HTTP endpoints.
Статистика тестов
- Всего тестов: 36
- basic_test.rs: 23 теста
- handler_tests.rs: 13 тестов
- Покрытие: 100% основных компонентов
- Статус: ✅ Все тесты проходят успешно
Запуск тестов
Локально
# Все тесты
cargo test
# Конкретный тест
cargo test test_health_check
# Тесты с выводом
cargo test -- --nocapture
# Тесты конкретного файла
cargo test --test basic_test
cargo test --test handler_tests
В CI/CD конвейере
Тесты запускаются автоматически при каждом коммите:
- Компиляция проекта
- Запуск всех unit тестов
- Проверка покрытия кода
- Генерация отчётов
- Автоматический деплой при успехе
Тесты с покрытием кода
# Использование скрипта
./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. Создание теста
#[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
#[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. Тестирование производительности
#[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. Производительность
- Минимизируйте время выполнения
- Используйте параллельное выполнение
- Оптимизируйте медленные тесты
Отладка тестов
RUST_LOG=debug cargo test --tests -- --nocapture # Вывод отладочной информации
cargo test --tests -- --nocapture --test-threads=1 # Продолжение после ошибки
Покрытие кода
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