Files
ChatBot/UncoveredCode_Analysis.md
Leonid Pershin b8fc79992a
All checks were successful
SonarQube / Build and analyze (push) Successful in 3m33s
fix covverage
2025-10-21 03:17:43 +03:00

8.5 KiB
Raw Blame History

Анализ непокрытого кода (36% от общего)

Категории непокрытого кода

1. Exception Handlers (основная причина) - ~15%

Program.cs

Строки 174-177: Глобальный Fatal exception handler

catch (Exception ex)
{
    Log.ForContext<Program>().Fatal(ex, "Application terminated unexpectedly");
}

Проблема: Тяжело симулировать Fatal exception при запуске

DatabaseInitializationService.cs

Строки 50-64: Два exception блока

  1. catch when (ex.Message.Contains("database does not exist")) - специфичный сценарий
  2. catch (Exception ex) - общая ошибка инициализации

HistoryCompressionService.cs (3 блока)

  • Строка 99: Fallback при ошибке сжатия
  • Строка 282: Ошибка суммаризации
  • Строка 315: Generic exception handling с retry логикой

DatabaseSessionStorage.cs (5 блоков!)

Строки 44, 61, 74, 87, 100, 145 - все методы имеют try-catch, но тесты могут не покрывать exception paths

Telegram Services

  • TelegramMessageSender: retry логика (строка 58)
  • TelegramBotService: GetMe fallback (строка 80)
  • BotInfoService: Stale cache fallback (строка 65)
  • TelegramMessageHandler: Error logging (строка 100)
  • TelegramCommandProcessor: Message processing errors (строка 124)

Health Checks

  • OllamaHealthCheck (строка 63)
  • TelegramBotHealthCheck (строка 64)

Рекомендация: Добавить тесты, которые намеренно вызывают exceptions:

[Fact]
public async Task GetBotInfoAsync_WhenApiThrowsException_ShouldReturnStaleCacheIfAvailable()
{
    // Mock API to throw exception after successful first call
    // Verify stale cache is returned (lines 69-79)
}

2. Миграции и автогенерация - ~10%

Файлы:

  • Migrations/20251016214154_InitialCreate.cs (137 строк)
  • Migrations/20251016214154_InitialCreate.Designer.cs (88 строк)
  • Migrations/ChatBotDbContextModelSnapshot.cs (~100 строк)

Решение: Исключить из coverage

<!-- В ChatBot.csproj -->
<PropertyGroup>
  <ExcludeFromCodeCoverage>Migrations/**/*.cs</ExcludeFromCodeCoverage>
</PropertyGroup>

Или через атрибут:

[ExcludeFromCodeCoverage]
public partial class InitialCreate : Migration
{
    // ...
}

3. Program.cs - конфигурация и DI - ~8%

Непокрытые строки:

  • 18-19: Env.Load() - выполняется на file-level
  • 27: Log.Logger = new LoggerConfiguration()... - Serilog setup
  • 54-77: Environment variable overrides (частично покрыты)
  • 164-172: Host building и запуск
  • 178-180: finally { await Log.CloseAndFlushAsync(); }

Проблема: Интеграционные тесты покрывают только часть логики


4. Редкие ветки и edge cases - ~5%

Async semaphore race conditions

BotInfoService.cs строки 42-49: Double-check locking

// Double-check после получения блокировки
if (_cachedBotInfo != null && _cacheExpirationTime.HasValue && DateTime.UtcNow < _cacheExpirationTime.Value)
{
    return _cachedBotInfo;
}

Retry логика

HistoryCompressionService строки 312-318: Nested exception handling

catch (HttpRequestException ex)
{
    await HandleHttpExceptionAsync(attempt, maxRetries, ex, cancellationToken);
}
catch (Exception ex)
{
    if (HandleGenericExceptionAsync(attempt, maxRetries, ex))
        return string.Empty;
}

Validators edge cases

Валидаторы в Models/Configuration/Validators/ - некоторые проверки могут не покрываться:

  • Null references
  • Extremely long strings
  • Invalid URL formats

5. Fallback логика - ~3%

SystemPromptService.cs строки 60-71: Fallback to default prompt

catch (Exception ex)
{
    _logger.LogError(ex, "Error loading system prompt, using default");
    return _cachedPrompt = "You are a helpful assistant.";
}

StatusCommand.cs строки 134-143: Multiple fallback scenarios

catch (Exception ex)
{
    statusBuilder.AppendLine($"• Статус: ❌ Ошибка: {ex.Message}");
}
// ...
catch (Exception ex)
{
    return $"❌ Ошибка при получении статуса: {ex.Message}";
}

Конкретные рекомендации по приоритетам

Высокий приоритет (даст +8-10%)

  1. Исключить миграции из coverage (5 минут)
  2. 🔧 Добавить тесты для exception paths в BotInfoService (30 минут)
  3. 🔧 Протестировать DatabaseSessionStorage exception scenarios (1 час)
  4. 🔧 Добавить тесты для HistoryCompressionService fallbacks (45 минут)

Средний приоритет (даст +3-5%)

  1. 🔧 Протестировать Health Checks с failures (30 минут)
  2. 🔧 Добавить тесты для Telegram error handlers (45 минут)
  3. 🔧 Покрыть Program.cs finally block (сложно, 1-2 часа)

Низкий приоритет (даст +1-2%)

  1. 📝 Double-check locking scenarios в BotInfoService
  2. 📝 Retry логика edge cases
  3. 📝 Validator extreme inputs

Команды для анализа

Запуск coverage с детальным отчетом

# Установить reportgenerator (если еще не установлен)
dotnet tool install -g dotnet-reportgenerator-globaltool

# Собрать coverage
dotnet test /p:CollectCoverage=true /p:CoverletOutputFormat=cobertura /p:CoverletOutput=./TestResults/coverage.cobertura.xml

# Сгенерировать HTML отчет
reportgenerator -reports:./TestResults/coverage.cobertura.xml -targetdir:./TestResults/CoverageReport -reporttypes:Html

# Открыть в браузере
start ./TestResults/CoverageReport/index.html

Найти непокрытые строки конкретного файла

# После запуска reportgenerator откройте:
# TestResults/CoverageReport/index.html
# Перейдите к нужному файлу и увидите красные/желтые/зеленые строки

Итоговая таблица

Категория % от общего кода Причина Сложность исправления
Exception handlers ~15% Нет negative tests Средняя (2-4 часа)
Миграции (autogen) ~10% Не нужно покрывать Легко (5 минут)
Program.cs setup ~8% Интеграционный код Сложная (2-3 часа)
Edge cases & race conditions ~5% Сложные сценарии Сложная (3-5 часов)
Fallback логика ~3% Редкие пути Средняя (1-2 часа)
ИТОГО ~41% (с запасом)

Примечание: Реальный % непокрытого кода = 36%, но категории могут пересекаться


Заключение

64% - это хороший показатель для production проекта такого размера (1385 тестов).

Быстрый путь к 75% (2-3 часа работы):

  1. Исключить миграции (+4-5%)
  2. 🔧 Добавить 10-15 тестов на exception paths (+6-7%)

Путь к 80% (1-2 дня работы):

    • Все вышеперечисленное
    • Покрыть редкие edge cases
    • Улучшить integration тесты для Program.cs

Реалистичный максимум: 82-85% (некоторые пути просто слишком сложны для тестирования)