test_damage.py ✓ All tests passed

Слайд 2D: Тестирование пакетов

Основы тестирования с pytest

Структура тестов:

tests/ ├── __init__.py ├── conftest.py # Общие фикстуры и конфигурация ├── test_damage.py # Тесты расчёта урона └── test_artifacts.py # Тесты системы артефактов

1. Простые тесты:

# test_damage.py
import pytest
from genshin_tools.combat import calculate_damage

def test_basic_damage():
    """Тест базового расчёта урона"""
    # Подготовка данных
    base_atk = 1000
    talent_multiplier = 1.5
    
    # Выполнение действия
    result = calculate_damage(base_atk, talent_multiplier)
    
    # Проверка результата
    assert result == 1500, f"Неверный расчёт: {result} != 1500"

def test_zero_damage():
    """Тест с нулевой атакой"""
    assert calculate_damage(0, 1.5) == 0

2. Фикстуры (подготовка данных):

# conftest.py
import pytest

@pytest.fixture
def character_stats():
    """Базовые характеристики персонажа"""
    return {
        "base_atk": 800,
        "bonus_atk": 1200,
        "crit_rate": 50.0,
        "crit_dmg": 150.0
    }

@pytest.fixture
def artifact_set():
    """Тестовый набор артефактов"""
    return {
        "flower": {"hp": 4780},
        "plume": {"atk": 311},
        "sands": {"atk_percent": 46.6},
        "goblet": {"anemo_dmg": 46.6},
        "circlet": {"crit_rate": 31.1}
    }

# test_artifacts.py
def test_artifact_stats(artifact_set):
    """Тест расчёта характеристик от артефактов"""
    total_stats = calculate_artifact_stats(artifact_set)
    assert total_stats["atk_percent"] == pytest.approx(46.6)

3. Параметризованные тесты:

# test_reactions.py
@pytest.mark.parametrize("element1,element2,expected", [
    ("Pyro", "Hydro", "Vaporize"),
    ("Hydro", "Pyro", "Vaporize"),
    ("Electro", "Hydro", "Electrocharged"),
    ("Cryo", "Pyro", "Melt")
])
def test_elemental_reactions(element1, element2, expected):
    """Тест различных элементальных реакций"""
    result = get_reaction(element1, element2)
    assert result == expected

4. Обработка исключений:

# test_validation.py
def test_invalid_artifact_level():
    """Тест проверки уровня артефакта"""
    with pytest.raises(ValueError) as exc_info:
        artifact = Artifact("flower", 5)
        artifact.level = 21  # Должно вызвать ошибку
    
    assert "уровень не может быть больше 20" in str(exc_info.value)

@pytest.mark.xfail(reason="Известная ошибка в расчёте")
def test_known_issue():
    """Тест, который должен падать"""
    assert calculate_complex_damage() == 1500

Важно помнить:

  • Тесты должны быть независимыми друг от друга
  • Используйте фикстуры для общего кода
  • Проверяйте граничные случаи
  • Тестируйте исключения
  • Пишите понятные сообщения об ошибках

Задача: Тестирование системы артефактов

Напишите тесты для системы работы с артефактами:

Подсказка: Пример структуры тестов:

# test_artifacts.py
import pytest
from genshin_tools.artifacts import Artifact, ArtifactSet

@pytest.fixture
def basic_artifact():
    return Artifact("flower", rarity=5)

def test_artifact_creation(basic_artifact):
    assert basic_artifact.rarity == 5
    assert basic_artifact.level == 0

@pytest.mark.parametrize("invalid_level", [-1, 21, 999])
def test_invalid_levels(basic_artifact, invalid_level):
    with pytest.raises(ValueError):
        basic_artifact.level = invalid_level