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

This commit is contained in:
Leonid Pershin
2025-10-21 04:06:00 +03:00
parent 800a3e97eb
commit 6d62c82947
5 changed files with 259 additions and 7 deletions

View File

@@ -0,0 +1,245 @@
# Финальное исправление: SonarQube 67.4% → 86.59%
## 🔍 Проблема "Coverage on New Code"
**SonarQube показывал**: 67.4% Coverage on New Code
**Причина**: Миграции EF Core не исключались из расчета coverage
---
## ✅ Окончательное решение
### 1. **Добавлен `[ExcludeFromCodeCoverage]` в файлы миграций**
#### `ChatBot/Migrations/20251016214154_InitialCreate.cs`
```csharp
using System.Diagnostics.CodeAnalysis;
using Microsoft.EntityFrameworkCore.Migrations;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
namespace ChatBot.Migrations
{
[ExcludeFromCodeCoverage] // ← Добавлено
public partial class InitialCreate : Migration
{
// ...
}
}
```
#### `ChatBot/Migrations/ChatBotDbContextModelSnapshot.cs`
```csharp
using System.Diagnostics.CodeAnalysis;
using ChatBot.Data;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
namespace ChatBot.Migrations
{
[DbContext(typeof(ChatBotDbContext))]
[ExcludeFromCodeCoverage] // ← Добавлено
partial class ChatBotDbContextModelSnapshot : ModelSnapshot
{
// ...
}
}
```
**Важно**: Для partial классов атрибут добавляется только в ОДИН файл!
---
### 2. **Улучшены параметры SonarQube в CI/CD**
#### `.gitea/workflows/build.yml`
```yaml
~/.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/**/*.cs,**/*ModelSnapshot.cs,**/Migrations/*.cs,**/Program.cs" \
/d:sonar.exclusions="**/Migrations/**/*.cs,**/obj/**,**/bin/**,**/TestResults/**" \
/d:sonar.cpd.exclusions="**/Migrations/**/*.cs" \
/d:sonar.sources="." \
/d:sonar.tests="." \
/d:sonar.test.inclusions="**/*Tests.cs,**/ChatBot.Tests/**/*.cs"
```
**Ключевые изменения**:
-`sonar.coverage.exclusions` - более точные glob паттерны для миграций
-`sonar.cpd.exclusions` - исключение из duplicate code detection
-`sonar.test.inclusions` - явное указание тестовых файлов
---
### 3. **Coverlet настроен для исключения миграций**
```bash
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% ✅
Tests: 1393/1393 passed ✅
========================================
```
---
## 🚀 Что делать дальше
### Commit и push всех изменений:
```bash
# Добавить все изменения
git add .gitea/workflows/build.yml
git add ChatBot/Migrations/20251016214154_InitialCreate.cs
git add ChatBot/Migrations/20251016214154_InitialCreate.Designer.cs
git add ChatBot/Migrations/ChatBotDbContextModelSnapshot.cs
git add ChatBot.Tests/ChatBot.Tests.csproj
git add run-coverage-detailed.ps1
git add .sonarqube/exclusions.txt
# Commit
git commit -m "Fix SonarQube coverage: add [ExcludeFromCodeCoverage] to migrations, improve exclusion patterns"
# Push
git push origin master
```
---
## 📈 Ожидаемый результат в SonarQube
### До:
```
❌ 67.4% Coverage on New Code
Required: 80.0%
FAILED
```
### После (ожидается):
```
✅ 86.59% Coverage on New Code
Required: 80.0%
PASSED 🎉
```
---
## 🎯 Почему это работает
### Комбинация трех методов исключения:
1. **`[ExcludeFromCodeCoverage]`** - атрибут C#
- Coverlet видит атрибут и пропускает эти классы
- Самый надежный способ
2. **`/p:ExcludeByFile="**/Migrations/*.cs"`** - параметр Coverlet
- Исключает файлы по паттерну
- Backup на случай, если атрибут не сработает
3. **`/d:sonar.coverage.exclusions`** - параметр SonarQube
- SonarQube дополнительно исключает эти файлы
- Двойная защита
---
## ⚠️ Важные замечания
### 1. Partial Classes и атрибуты
Для partial классов `[ExcludeFromCodeCoverage]` применяется только к **ОДНОЙ** части:
```csharp
// InitialCreate.cs
[ExcludeFromCodeCoverage] // ✅ Добавить здесь
public partial class InitialCreate : Migration
// InitialCreate.Designer.cs
partial class InitialCreate // ❌ НЕ добавлять здесь (дублирование)
```
### 2. "Coverage on New Code" vs "Overall Coverage"
- **Overall Coverage**: покрытие всего проекта
- **Coverage on New Code**: покрытие только новых изменений в текущей ветке
SonarQube может показывать разные значения для этих метрик. После merge в master оба значения станут одинаковыми.
### 3. Автоматическая регенерация миграций
Если вы создадите новые миграции через `dotnet ef migrations add`, не забудьте:
1. Добавить `using System.Diagnostics.CodeAnalysis;`
2. Добавить `[ExcludeFromCodeCoverage]` к классу миграции
3. Добавить `[ExcludeFromCodeCoverage]` к ModelSnapshot (если изменился)
---
## 🔍 Проверка перед push
### Локальный тест:
```powershell
.\run-coverage-detailed.ps1
```
### Ожидаемый output:
```
Line Coverage: 86.59%
Branch Coverage: 76.01%
🎉 Excellent coverage (80%+)
```
Если видите **86.59%** - значит все настроено правильно! ✅
---
## 📝 Файлы, которые были изменены
### Основные изменения:
1.`.gitea/workflows/build.yml` - улучшены параметры SonarQube
2.`ChatBot/Migrations/*.cs` - добавлен `[ExcludeFromCodeCoverage]`
3.`ChatBot.Tests/ChatBot.Tests.csproj` - добавлен coverlet.msbuild
4.`run-coverage-detailed.ps1` - скрипт для проверки coverage
5.`.sonarqube/exclusions.txt` - документация по исключениям
### Удалены:
-`sonar-project.properties` - не используется SonarScanner for .NET
---
## 🎉 Итоговая статистика
| Метрика | Значение | Статус |
|---------|----------|--------|
| **Line Coverage** | 86.59% | ✅ Выше 80% |
| **Branch Coverage** | 76.01% | ✅ Приемлемо |
| **Всего тестов** | 1393 | ✅ Все проходят |
| **Новые тесты** | +8 | ✅ Добавлены |
| **SonarQube Quality Gate** | PASSED (ожидается) | ✅ |
---
## 🏆 Результат
**Проблема полностью решена!**
Комбинация `[ExcludeFromCodeCoverage]` атрибутов + улучшенных glob паттернов в SonarQube + правильной конфигурации coverlet обеспечивает:
-**86.59%** coverage локально
-**~86-87%** coverage в SonarQube (ожидается)
- ✅ Проходит Quality Gate (требование 80%)
- ✅ Миграции полностью исключены из расчета
**Готово к push!** 🚀