Files
quoter/docs/testing.md
Untone a44bf3302b
Some checks failed
Deploy / deploy (push) Has been skipped
CI / test (push) Successful in 6m50s
CI / lint (push) Failing after 1m5s
test-fix
2025-08-12 15:59:51 +03:00

14 KiB
Raw Blame History

Тестирование

Этот документ описывает подход к тестированию проекта 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 конвейере

Тесты запускаются автоматически при каждом коммите:

  1. Компиляция проекта
  2. Запуск всех unit тестов
  3. Проверка покрытия кода
  4. Генерация отчётов
  5. Автоматический деплой при успехе

Тесты с покрытием кода

# Использование скрипта
./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