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

199 lines
7.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Тестирование
Этот документ описывает подход к тестированию проекта Quoter.
## Обзор
Проект использует интеграционные тесты для проверки функциональности без внешних зависимостей. Тесты написаны на Rust с использованием фреймворка Actix Web для тестирования HTTP endpoints.
## Запуск тестов
### Все тесты
```bash
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. Создание теста
```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 интеграция
Тесты автоматически запускаются в CI/CD pipeline