fix covverage
All checks were successful
SonarQube / Build and analyze (push) Successful in 3m33s

This commit is contained in:
Leonid Pershin
2025-10-21 03:17:43 +03:00
parent 2a26e84100
commit b8fc79992a
8 changed files with 837 additions and 0 deletions

226
UncoveredCode_Analysis.md Normal file
View File

@@ -0,0 +1,226 @@
# Анализ непокрытого кода (36% от общего)
## Категории непокрытого кода
### 1. Exception Handlers (основная причина) - ~15%
#### Program.cs
**Строки 174-177**: Глобальный Fatal exception handler
```csharp
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:
```csharp
[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
```xml
<!-- В ChatBot.csproj -->
<PropertyGroup>
<ExcludeFromCodeCoverage>Migrations/**/*.cs</ExcludeFromCodeCoverage>
</PropertyGroup>
```
Или через атрибут:
```csharp
[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
```csharp
// Double-check после получения блокировки
if (_cachedBotInfo != null && _cacheExpirationTime.HasValue && DateTime.UtcNow < _cacheExpirationTime.Value)
{
return _cachedBotInfo;
}
```
#### Retry логика
**HistoryCompressionService строки 312-318**: Nested exception handling
```csharp
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
```csharp
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
```csharp
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 с детальным отчетом
```powershell
# Установить 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
```
### Найти непокрытые строки конкретного файла
```powershell
# После запуска 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%** (некоторые пути просто слишком сложны для тестирования)