Files
quoter/docs/testing.md
Untone ea92a376ed
Some checks failed
CI / test (push) Failing after 4m0s
CI / lint (push) Failing after 4s
CI / deploy (push) Has been skipped
docs
2025-08-02 00:18:09 +03:00

7.6 KiB
Raw Blame History

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

Этот документ описывает подход к тестированию проекта Quoter.

Обзор

Проект использует интеграционные тесты для проверки функциональности без внешних зависимостей. Тесты написаны на Rust с использованием фреймворка Actix Web для тестирования HTTP endpoints.

Запуск тестов

Все тесты

cargo test --tests # все
cargo test --test basic_test test_health_check # конкретный тест
cargo test --tests -- --nocapture # Тесты с выводом

Описание тестов

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)
  • Вывод статистики производительности

Принципы тестирования

1. Изоляция

  • Тесты не зависят от внешних сервисов (Redis, S3)
  • Каждый тест независим от других
  • Используются моки и заглушки

2. Покрытие

  • Тестируются основные функции
  • Проверяются граничные случаи
  • Тестируется обработка ошибок

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 интеграция

Тесты автоматически запускаются в CI/CD pipeline