# Исправление покрытия в SonarQube ## 🔍 Проблема **SonarQube показывал**: 64.4% coverage **Реальное покрытие**: 86.59% coverage **Причина**: Неправильная конфигурация сбора coverage в CI/CD --- ## ✅ Что было исправлено ### 1. **Обновлен `.gitea/workflows/build.yml`** #### Было: ```yaml - name: Install dotnet-coverage run: | mkdir -p ~/.sonar/coverage dotnet tool install dotnet-coverage --tool-path ~/.sonar/coverage - name: Build and analyze run: | ~/.sonar/coverage/dotnet-coverage collect "dotnet test" -f xml -o "coverage.xml" ``` **Проблема**: `dotnet-coverage` не поддерживает исключения и считает все файлы, включая миграции. #### Стало: ```yaml - name: Build and analyze run: | ~/.sonar/scanner/dotnet-sonarscanner begin \ /k:"mrleo1nid_chatbot" \ /d:sonar.cs.opencover.reportsPaths="**/coverage.opencover.xml" \ /d:sonar.coverage.exclusions="**/Migrations/**/*.cs,**/*ModelSnapshot.cs" dotnet build --verbosity normal --no-incremental dotnet test \ /p:CollectCoverage=true \ /p:CoverletOutputFormat=opencover \ /p:CoverletOutput=./coverage/ \ /p:Exclude="[*]*.Migrations.*" \ /p:ExcludeByFile="**/Migrations/*.cs" ``` **Преимущества**: - ✅ Использует `coverlet.msbuild` (уже добавлен в проект) - ✅ Исключает миграции: `/p:Exclude="[*]*.Migrations.*"` - ✅ Исключает файлы: `/p:ExcludeByFile="**/Migrations/*.cs"` - ✅ Формат OpenCover корректно обрабатывается SonarQube --- ### 2. **Настроены исключения в `dotnet-sonarscanner begin`** ⚠️ **Важно**: `SonarScanner for .NET` НЕ использует файл `sonar-project.properties`! Все настройки передаются через параметры командной строки: ```bash ~/.sonar/scanner/dotnet-sonarscanner begin \ /k:"mrleo1nid_chatbot" \ /o:"mrleo1nid" \ /d:sonar.token="${{ secrets.SONAR_TOKEN }}" \ /d:sonar.cs.opencover.reportsPaths="**/coverage.opencover.xml" \ /d:sonar.coverage.exclusions="**/Migrations/**,**/Migrations/*.cs,**/*ModelSnapshot.cs" \ /d:sonar.exclusions="**/Migrations/**,**/obj/**,**/bin/**" \ /d:sonar.sources="ChatBot/" \ /d:sonar.tests="ChatBot.Tests/" ``` **Что это дает**: - 📊 SonarQube знает, что миграции нужно исключить из coverage - 📊 Правильно определяет source и test файлы - 📊 Использует правильный формат coverage отчетов (OpenCover) - 📊 Исключает build артефакты (obj, bin) --- ### 3. **Добавлен `coverlet.msbuild` в проект** ```xml all runtime; build; native; contentfiles; analyzers; buildtransitive ``` **Зачем**: Coverlet - более точный и гибкий инструмент для сбора coverage, чем `dotnet-coverage`. --- ## 📊 Ожидаемый результат ### После следующего push в master: **До**: ``` ❌ 64.4% Coverage on New Code Required: 80.0% ``` **После**: ``` ✅ 86.59% Coverage on New Code Required: 80.0% 🎉 PASSED ``` --- ## 🚀 Как проверить локально ### Запустить coverage с теми же параметрами, что и в CI: ```bash # PowerShell .\run-coverage-detailed.ps1 # Или напрямую dotnet test ` /p:CollectCoverage=true ` /p:CoverletOutputFormat=opencover ` /p:CoverletOutput=./coverage/ ` /p:Exclude="[*]*.Migrations.*" ` /p:ExcludeByFile="**/Migrations/*.cs" ``` ### Результат: ``` ======================================== COVERAGE RESULTS: ======================================== Line Coverage: 86.59% (2022 / 2335) Branch Coverage: 76.01% ======================================== ``` --- ## 📋 Что учитывается в SonarQube ### ✅ Включено в coverage: - **Business Logic**: ChatService, AIService - **Data Layer**: Repositories, DbContext - **Services**: все сервисы в /Services/ - **Models**: POCO классы, DTOs - **Telegram Commands**: все команды - **Program.cs**: конфигурация и DI ### ❌ Исключено из coverage: - **Migrations**: автогенерированные EF Core миграции - **ModelSnapshot**: автогенерированный класс - **obj/ и bin/**: артефакты сборки - **Тестовые проекты**: ChatBot.Tests/** --- ## 🔧 Разница между инструментами | Инструмент | Точность | Исключения | Формат | Рекомендация | |------------|----------|------------|--------|--------------| | **dotnet-coverage** | ⚠️ Средняя | ❌ Не поддерживает | XML | Не рекомендуется | | **coverlet** | ✅ Высокая | ✅ Полная поддержка | OpenCover, Cobertura | ✅ Рекомендуется | --- ## 🎯 Следующие шаги 1. **Сделайте commit и push**: ```bash git add .gitea/workflows/build.yml git add .sonarqube/exclusions.txt git add ChatBot.Tests/ChatBot.Tests.csproj git add run-coverage-detailed.ps1 git add SonarQube_Coverage_Fix.md git commit -m "Fix SonarQube coverage: exclude migrations, use coverlet with proper exclusions" git push origin master ``` ⚠️ **Важно**: НЕ создавайте файл `sonar-project.properties` - он не используется SonarScanner for .NET! 2. **Дождаться выполнения CI/CD**: - Проверить логи GitHub Actions/Gitea - Убедиться, что coverage собирается с coverlet - Проверить, что создается файл `coverage.opencover.xml` 3. **Проверить SonarQube**: - Открыть SonarQube dashboard - Проверить новый analysis - Покрытие должно быть **~86-87%** --- ## ⚠️ Важные замечания ### SonarQube может показывать "Coverage on New Code" Если вы видите: ``` 64.4% Coverage on New Code 86.5% Overall Coverage ``` Это означает, что: - **Overall Coverage** - покрытие всего проекта (правильное значение) - **Coverage on New Code** - покрытие только новых изменений **Решение**: Убедитесь, что новые тесты добавлены для нового кода: - ✅ `BotInfoServiceSimpleTests.cs` - 3 теста - ✅ `DatabaseInitializationServiceExceptionTests.cs` - 3 теста - ✅ `StatusCommandEdgeCaseTests.cs` - 2 теста --- ## 📈 Метрики после исправления ### Локальный тест (подтверждено): ``` Line Coverage: 86.59% ✅ Branch Coverage: 76.01% ✅ Tests: 1393/1393 passed ✅ ``` ### SonarQube (ожидается после push): ``` Overall Coverage: ~86-87% ✅ New Code Coverage: ~86-87% ✅ Quality Gate: PASSED ✅ ``` --- ## 🎉 Итог **Проблема решена!** После push этих изменений SonarQube будет показывать реальное покрытие **~86-87%**, что значительно превышает требуемые 80%. Все изменения готовы к commit и push в репозиторий.