Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 23 additions & 16 deletions .github/workflows/android.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Android quality checks
name: Quality Checks

on:
push:
Expand All @@ -8,12 +8,12 @@ on:

jobs:
check:

runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v6
- name: set up JDK

- name: Set up JDK
uses: actions/setup-java@v5
with:
java-version: '21'
Expand All @@ -22,19 +22,26 @@ jobs:

- name: Grant execute permission for gradlew
run: chmod +x gradlew
- name: Check build

- name: Run all checks
run: ./gradlew check
continue-on-error: true

- name: Save Gradle cache
uses: actions/cache@v5
continue-on-error: true

- name: Generate coverage report
run: ./gradlew koverXmlReport

- name: Upload test results
if: always()
uses: actions/upload-artifact@v6
with:
name: test-results
path: |
**/build/test-results/
**/build/reports/tests/

- name: Upload coverage reports
if: always()
uses: actions/upload-artifact@v6
with:
name: coverage-reports
path: |
~/.gradle/caches
~/.gradle/wrapper
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
restore-keys: |
${{ runner.os }}-gradle-

**/build/reports/kover/
57 changes: 35 additions & 22 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Build libs
name: Build & Test

on:
push:
Expand All @@ -7,12 +7,12 @@ on:

jobs:
check:

runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v6
- name: set up JDK

- name: Set up JDK
uses: actions/setup-java@v5
with:
java-version: '21'
Expand All @@ -21,28 +21,41 @@ jobs:

- name: Grant execute permission for gradlew
run: chmod +x gradlew

- name: Check build
run: ./gradlew :vbpd-core:assembleRelease :vbpd:assembleRelease :vbpd-reflection:assembleRelease --no-configuration-cache --no-build-cache
continue-on-error: true

- name: Save Gradle cache
uses: actions/cache@v5
continue-on-error: true

- name: Build libraries
run: ./gradlew :vbpd-core:assembleRelease :vbpd:assembleRelease :vbpd-reflection:assembleRelease

- name: Run tests
run: ./gradlew testDebugUnitTest

- name: Run code quality checks
run: ./gradlew detekt ktlintCheck

- name: Generate coverage report
run: ./gradlew koverXmlReport

- name: Upload test results
if: always()
uses: actions/upload-artifact@v6
with:
name: test-results
path: |
**/build/test-results/
**/build/reports/tests/

- name: Upload coverage reports
if: always()
uses: actions/upload-artifact@v6
with:
name: coverage-reports
path: |
~/.gradle/caches
~/.gradle/wrapper
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
restore-keys: |
${{ runner.os }}-gradle-
**/build/reports/kover/

- name: Save build artifacts
- name: Upload build artifacts
uses: actions/upload-artifact@v6
with:
name: vbpd-libs-builds
path:
vbpd/build/outputs/aar/vbpd-release.aar
vbpd-core/build/outputs/aar/vbpd-core-release.aar
vbpd-reflection/build/outputs/aar/vbpd-reflection-release.aar

path: |
vbpd-core/build/outputs/aar/*.aar
vbpd/build/outputs/aar/*.aar
vbpd-reflection/build/outputs/aar/*.aar
42 changes: 42 additions & 0 deletions config/detekt/detekt.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
build:
maxIssues: 0

complexity:
LongMethod:
threshold: 60
LongParameterList:
functionThreshold: 8
constructorThreshold: 8
TooManyFunctions:
thresholdInFiles: 20
thresholdInClasses: 15
thresholdInInterfaces: 10

empty-blocks:
EmptyFunctionBlock:
ignoreOverridden: true

exceptions:
SwallowedException:
ignoredExceptionTypes:
- NoSuchMethodException

naming:
FunctionNaming:
functionPattern: '[a-zA-Z][a-zA-Z0-9]*'
MatchingDeclarationName:
active: false
MemberNameEqualsClassName:
active: false

style:
MaxLineLength:
active: false
WildcardImport:
active: false
MagicNumber:
active: false
ReturnCount:
max: 3
UnusedPrivateMember:
active: true
87 changes: 87 additions & 0 deletions docs/plans/2026-02-14-tests-and-quality-design.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
# ViewBindingPropertyDelegate: Тесты и Качество кода

**Дата**: 2026-02-14
**Статус**: Одобрен
**Версия библиотеки**: 2.0.4

## Цель

Добавить тестовое покрытие, статический анализ и контроль качества кода в проект ViewBindingPropertyDelegate. Исправить CI/CD пайплайн.

## Решения

### Подход

«Фундамент сначала» — последовательная стратегия:
1. Инструменты (Detekt + ktlint + Kover) → 2. Исправление замечаний линтеров → 3. Тесты → 4. CI

### Тестовый стек

| Инструмент | Назначение |
|---|---|
| kotlin.test | Ассерты (Kotlin-нативные) |
| JUnit4 | Раннер (совместимость с Robolectric и AndroidX Test) |
| AndroidX Test | ActivityScenario, FragmentScenario — единое API для локальных и instrumented тестов |
| Robolectric | Локальный запуск Android-тестов без эмулятора |
| MockK | Kotlin-нативный мокинг |

### Инструменты качества

| Инструмент | Назначение |
|---|---|
| Detekt | Статический анализ Kotlin-кода |
| ktlint | Форматирование и стиль кода |
| Kover | Измерение покрытия тестами (JetBrains) |

## Секция 1: Инфраструктура качества кода

### Detekt
- Подключается через convention plugin `vbpdconfig.gradle.kts`
- Кастомный `detekt.yml` с правилами для библиотеки
- Задача `detekt` добавляется в `check`

### ktlint
- Через плагин `ktlint-gradle`
- Стандартные Kotlin Coding Conventions
- Задача `ktlintCheck` добавляется в `check`

### Kover
- Подключается через convention plugin
- HTML и XML отчёты
- Минимальный порог покрытия: 60% (с планом повышения)

## Секция 2: Тестовое покрытие

### vbpd-core (юнит-тесты)
- `LazyViewBindingProperty` — ленивая инициализация, кэширование, очистка
- `EagerViewBindingProperty` — немедленная инициализация

### vbpd (Robolectric + AndroidX Test)
- `ActivityViewBindingProperty` — lifecycle Activity, очистка при onDestroy
- `FragmentViewBindingProperty` — lifecycle Fragment, очистка при onDestroyView
- `ViewGroupBindings` — обычный режим / edit mode
- `ViewHolderBindings` — привязка к ViewHolder
- DialogFragment — специальная обработка

### vbpd-reflection (юнит + Robolectric)
- `ViewBindingCache` — включение/выключение, корректность
- Рефлексия: BIND vs INFLATE, merge-layouts
- Lifecycle-тесты с reflection API

## Секция 3: Исправление CI

### build.yml (develop)
- Убрать `continue-on-error: true`
- Добавить `testReleaseUnitTest`
- Добавить `detekt`, `ktlintCheck`
- Добавить `koverXmlReport`

### android.yml (master)
- Аналогичные проверки для PR
- Upload coverage report как артефакт

## Что НЕ входит в скоуп
- Git pre-commit hooks
- Изменение существующего публичного API
- Новые фичи библиотеки
- Автоматизация публикации на Maven Central
Loading