CI/CD Integration: GitHub Actions, Coverage & Pre-commit Hooks

 GitHub Actions Workflows:
- tests.yml: Automatische Tests auf Python 3.9-3.12
- coverage.yml: Coverage Reports mit Badge & Artifacts

 Test Infrastructure:
- .coveragerc: Coverage-Konfiguration
- run_coverage.sh: Lokales Coverage-Script
- .githooks/pre-commit: Template für lokale Test-Validierung

 Dokumentation:
- CI_CD.md: Umfassende CI/CD-Dokumentation (Workflows, Hooks, Best Practices)
- README.md: Tests & CI/CD Sektion erweitert mit Badges und Übersicht

Features:
- Multi-Python-Version Support (Matrix Build)
- Automatische Test-Ausführung bei Push/PR
- Coverage-Reports mit HTML-Artefakten
- Pre-commit Hooks für lokale Validierung
- Code Quality Checks (flake8)
- GitHub Actions Summary Integration

Die Test-Suite ist jetzt vollständig in CI/CD integriert! 🚀

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
jamulix 2025-10-29 09:57:48 +01:00
commit dce65cc692
7 changed files with 694 additions and 17 deletions

25
.coveragerc Normal file
View file

@ -0,0 +1,25 @@
[run]
source = .
omit =
*/tests/*
*/venv/*
*/__pycache__/*
*/migrations/*
setup.py
setup_database.py
[report]
exclude_lines =
pragma: no cover
def __repr__
raise AssertionError
raise NotImplementedError
if __name__ == .__main__.:
if TYPE_CHECKING:
@abstractmethod
precision = 2
show_missing = True
[html]
directory = htmlcov

46
.githooks/pre-commit Executable file
View file

@ -0,0 +1,46 @@
#!/bin/bash
# Pre-commit hook für Typewriter Trainer
# Führt automatisch Tests aus vor jedem Commit
#
# Installation:
# cp .githooks/pre-commit .git/hooks/pre-commit
# chmod +x .git/hooks/pre-commit
echo "🧪 Running tests before commit..."
echo ""
# Farben für Output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# Unit Tests ausführen (schnell)
echo "📋 Running Unit Tests..."
if python -m unittest tests.test_lesson_service tests.test_statistics_service tests.test_settings_service -v 2>&1 | grep -q "OK"; then
echo -e "${GREEN}✅ Unit Tests passed${NC}"
else
echo -e "${RED}❌ Unit Tests failed${NC}"
echo ""
echo "Please fix the tests before committing."
exit 1
fi
echo ""
# Integration Tests ausführen
echo "🔗 Running Integration Tests..."
if python -m unittest tests.test_integration_progress tests.test_integration_statistics -v 2>&1 | grep -q "OK"; then
echo -e "${GREEN}✅ Integration Tests passed${NC}"
else
echo -e "${RED}❌ Integration Tests failed${NC}"
echo ""
echo "Please fix the tests before committing."
exit 1
fi
echo ""
echo -e "${GREEN}✅ All tests passed! Proceeding with commit...${NC}"
echo ""
exit 0

90
.github/workflows/coverage.yml vendored Normal file
View file

@ -0,0 +1,90 @@
name: Coverage
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main, develop ]
workflow_dispatch:
jobs:
coverage:
name: Test Coverage
runs-on: ubuntu-latest
steps:
- name: Checkout Code
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
cache: 'pip'
- name: Install Dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
pip install coverage
- name: Run Tests with Coverage
run: |
coverage run -m unittest discover -s tests -p "test_*.py"
coverage report -m
coverage html
- name: Generate Coverage Badge
run: |
COVERAGE=$(coverage report | grep TOTAL | awk '{print $4}' | sed 's/%//')
echo "Coverage: $COVERAGE%"
# Create badge color
if (( $(echo "$COVERAGE >= 90" | bc -l) )); then
COLOR="brightgreen"
elif (( $(echo "$COVERAGE >= 75" | bc -l) )); then
COLOR="green"
elif (( $(echo "$COVERAGE >= 60" | bc -l) )); then
COLOR="yellow"
else
COLOR="red"
fi
echo "COVERAGE=$COVERAGE" >> $GITHUB_ENV
echo "COLOR=$COLOR" >> $GITHUB_ENV
- name: Upload Coverage Report
uses: actions/upload-artifact@v4
with:
name: coverage-report
path: htmlcov/
retention-days: 30
- name: Coverage Summary
run: |
echo "# Coverage Report" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "![Coverage](https://img.shields.io/badge/coverage-${{ env.COVERAGE }}%25-${{ env.COLOR }})" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "## Detailed Coverage" >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
coverage report >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "Full HTML report available as artifact." >> $GITHUB_STEP_SUMMARY
- name: Comment Coverage on PR
if: github.event_name == 'pull_request'
uses: actions/github-script@v7
with:
script: |
const coverage = process.env.COVERAGE;
const color = process.env.COLOR;
const body = `## 📊 Coverage Report\n\n![Coverage](https://img.shields.io/badge/coverage-${coverage}%25-${color})\n\nDetailed report available in artifacts.`;
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});

116
.github/workflows/tests.yml vendored Normal file
View file

@ -0,0 +1,116 @@
name: Tests
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main, develop ]
workflow_dispatch:
jobs:
test:
name: Run Tests
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ['3.9', '3.10', '3.11', '3.12']
steps:
- name: Checkout Code
uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
cache: 'pip'
- name: Install Dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
- name: Run Unit Tests
run: |
python -m unittest tests.test_lesson_service tests.test_statistics_service tests.test_settings_service -v
- name: Run Integration Tests
run: |
python -m unittest tests.test_integration_progress tests.test_integration_statistics -v
- name: Run All Tests
run: |
python -m unittest discover -s tests -p "test_*.py" -v
test-summary:
name: Test Summary
runs-on: ubuntu-latest
needs: test
if: always()
steps:
- name: Checkout Code
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
cache: 'pip'
- name: Install Dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
- name: Generate Test Summary
run: |
echo "# Test Results" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "## Test Execution" >> $GITHUB_STEP_SUMMARY
python -m unittest discover -s tests -p "test_*.py" -v 2>&1 | tee test_output.txt
# Parse test results
TESTS_RUN=$(grep -o "Ran [0-9]* test" test_output.txt | grep -o "[0-9]*" || echo "0")
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Tests Run:** $TESTS_RUN" >> $GITHUB_STEP_SUMMARY
if grep -q "OK" test_output.txt; then
echo "**Status:** ✅ All tests passed!" >> $GITHUB_STEP_SUMMARY
else
echo "**Status:** ❌ Some tests failed" >> $GITHUB_STEP_SUMMARY
fi
echo "" >> $GITHUB_STEP_SUMMARY
echo "### Test Details" >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
tail -20 test_output.txt >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
lint:
name: Code Quality
runs-on: ubuntu-latest
steps:
- name: Checkout Code
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Install flake8
run: |
python -m pip install --upgrade pip
pip install flake8
- name: Lint with flake8
run: |
# Stop the build if there are Python syntax errors or undefined names
flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
# Exit-zero treats all errors as warnings
flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
continue-on-error: true

319
CI_CD.md Normal file
View file

@ -0,0 +1,319 @@
# CI/CD Integration - Typewriter Trainer
Dieses Dokument beschreibt die Continuous Integration und Continuous Deployment (CI/CD) Setup für den Typewriter Trainer.
## Übersicht
Die Test-Suite ist vollständig in CI/CD-Pipelines integriert und bietet:
- ✅ **Automatische Tests** bei jedem Push und Pull Request
- ✅ **Multi-Python-Version Support** (3.9, 3.10, 3.11, 3.12)
- ✅ **Coverage Reports** mit HTML-Visualisierung
- ✅ **Pre-commit Hooks** für lokale Validierung
- ✅ **Code Quality Checks** (flake8 Linting)
## GitHub Actions Workflows
### 1. Tests Workflow (`.github/workflows/tests.yml`)
**Trigger:**
- Push auf `main` und `develop` Branches
- Pull Requests auf `main` und `develop`
- Manuell über `workflow_dispatch`
**Jobs:**
#### Test Job
- Führt Tests auf Python 3.9, 3.10, 3.11, 3.12 aus
- Installiert Dependencies aus `requirements.txt`
- Führt Unit Tests aus (schnell, < 1 Sekunde)
- Führt Integration Tests aus (~3 Sekunden)
- Führt alle Tests kombiniert aus
- Matrix-Build für Multi-Version-Kompatibilität
#### Test Summary Job
- Läuft nach allen Tests (immer, auch bei Fehlern)
- Generiert Test-Zusammenfassung in GitHub Actions Summary
- Zeigt Anzahl der Tests und Status an
#### Lint Job
- Code Quality Check mit flake8
- Prüft auf Syntax-Fehler und undefined names
- Complexity und Line-Length Checks (nicht blockierend)
**Badge Status:**
```markdown
![Tests](https://github.com/jamulix/typewriter/actions/workflows/tests.yml/badge.svg)
```
### 2. Coverage Workflow (`.github/workflows/coverage.yml`)
**Trigger:**
- Push auf `main` und `develop` Branches
- Pull Requests auf `main` und `develop`
- Manuell über `workflow_dispatch`
**Features:**
- Generiert Test Coverage Report mit `coverage.py`
- Erstellt HTML Coverage Report als Artifact
- Berechnet Coverage-Prozentsatz
- Generiert dynamisches Coverage-Badge (grün ≥90%, gelb ≥60%, rot <60%)
- Kommentiert Coverage auf Pull Requests
- Speichert HTML-Report für 30 Tage
**Badge Status:**
```markdown
![Coverage](https://github.com/jamulix/typewriter/actions/workflows/coverage.yml/badge.svg)
```
**Coverage Report anzeigen:**
1. Gehe zu Actions → Coverage Workflow → Latest Run
2. Lade "coverage-report" Artifact herunter
3. Öffne `htmlcov/index.html` im Browser
## Lokale Test-Ausführung
### Alle Tests ausführen
```bash
# Alle Tests (Unit + Integration)
python -m unittest discover -s tests -p "test_*.py" -v
# Nur Unit Tests (schnell)
python -m unittest tests.test_lesson_service tests.test_statistics_service tests.test_settings_service -v
# Nur Integration Tests
python -m unittest tests.test_integration_progress tests.test_integration_statistics -v
```
### Coverage Report generieren
**Mit Script:**
```bash
./run_coverage.sh
```
**Manuell:**
```bash
# Coverage installieren
pip install coverage
# Tests mit Coverage ausführen
coverage run -m unittest discover -s tests -p "test_*.py"
# Terminal Report
coverage report -m
# HTML Report
coverage html
# Öffne htmlcov/index.html im Browser
```
## Pre-commit Hooks
### Automatische Test-Validierung vor jedem Commit
Der Pre-commit Hook führt automatisch alle Tests aus, bevor ein Commit erstellt wird.
**Installation:**
```bash
# Hook ist bereits installiert in .git/hooks/pre-commit
# Falls nicht, kopiere aus Template:
cp .githooks/pre-commit .git/hooks/pre-commit
chmod +x .git/hooks/pre-commit
```
**Funktionsweise:**
1. ✅ Führt Unit Tests aus
2. ✅ Führt Integration Tests aus
3. ✅ Blockiert Commit bei Test-Fehlern
4. ✅ Zeigt farbiges Output für bessere Übersicht
**Hook überspringen (nicht empfohlen):**
```bash
git commit --no-verify -m "message"
```
## Test-Statistiken
### Gesamt-Übersicht
| Kategorie | Anzahl | Status |
|-----------|--------|--------|
| **Gesamt Tests** | 80 | ✅ 100% |
| **Unit Tests** | 54 | ✅ Bestanden |
| **Integration Tests** | 26 | ✅ Bestanden |
| **Ausführungszeit** | ~2.9s | ⚡ Schnell |
### Unit Tests Breakdown
| Service | Tests | Coverage |
|---------|-------|----------|
| LessonService | 17 | Navigation & Validierung |
| StatisticsService | 15 | Berechnungen (ZPM/WPM) |
| SettingsService | 22 | Validierungen |
### Integration Tests Breakdown
| Service | Tests | Coverage |
|---------|-------|----------|
| ProgressService | 12 | CRUD & State Management |
| StatisticsService | 14 | DB Operations & Daily Practice |
## Coverage Konfiguration
Die Coverage-Konfiguration ist in `.coveragerc` definiert:
```ini
[run]
source = .
omit =
*/tests/*
*/venv/*
*/migrations/*
setup.py
[report]
precision = 2
show_missing = True
[html]
directory = htmlcov
```
**Ausgeschlossene Dateien:**
- Test-Dateien selbst
- Virtual Environments
- Migrations
- Setup-Scripts
## Best Practices
### Für Entwickler
1. **Immer Tests schreiben** für neue Features
2. **Lokale Tests ausführen** vor dem Push:
```bash
python -m unittest discover tests -v
```
3. **Coverage checken** für neue Code-Bereiche:
```bash
./run_coverage.sh
```
4. **Pre-commit Hook aktiv lassen** für automatische Validierung
### Für Pull Requests
1. ✅ Alle Tests müssen bestehen (automatisch geprüft)
2. ✅ Coverage sollte nicht sinken
3. ✅ Lint-Checks sollten bestehen
4. ✅ Review GitHub Actions Summary
### Für Releases
1. Erstelle Branch von `develop`
2. Alle Tests auf `main` müssen grün sein
3. Coverage Report prüfen
4. Merge nach `main` → automatische Tests laufen
## Troubleshooting
### Tests schlagen in CI fehl, aber lokal nicht
**Mögliche Ursachen:**
- Python-Version unterschiedlich (CI tested 3.9-3.12)
- Dependencies nicht korrekt in `requirements.txt`
- Plattform-spezifische Unterschiede (Linux vs. macOS/Windows)
**Lösung:**
```bash
# Teste mit verschiedenen Python-Versionen lokal
python3.9 -m unittest discover tests -v
python3.11 -m unittest discover tests -v
```
### Coverage Report zeigt falsche Werte
**Lösung:**
```bash
# Lösche alte Coverage-Daten
rm -rf .coverage htmlcov/
# Neu generieren
./run_coverage.sh
```
### Pre-commit Hook blockiert Commit
**Das ist gewollt!** Der Hook verhindert, dass fehlerhafte Tests in den Code kommen.
**Lösung:**
1. Prüfe Test-Output: `python -m unittest discover tests -v`
2. Fixe die fehlschlagenden Tests
3. Commit erneut
**Nur in Notfällen umgehen:**
```bash
git commit --no-verify -m "message"
```
### GitHub Actions schlagen fehl mit "Module not found"
**Lösung:**
- Stelle sicher, dass alle Dependencies in `requirements.txt` sind
- Prüfe ob `requirements.txt` im Repository committed ist
## Workflow-Diagramm
```
┌─────────────────────────────────────────────────────────────┐
│ Developer Workflow │
└─────────────────────────────────────────────────────────────┘
1. Code ändern
2. Lokale Tests (optional)
│ ./run_coverage.sh
3. git add / git commit
4. Pre-commit Hook
│ ✅ Unit Tests
│ ✅ Integration Tests
│ ❌ Blockiert bei Fehler
5. git push
┌────────────────────────┐
│ GitHub Actions │
├────────────────────────┤
│ • Tests (Multi-Python) │
│ • Coverage Report │
│ • Lint Check │
│ • Artifact Upload │
└────────────────────────┘
6. Review & Merge
```
## Weitere Ressourcen
- **Test-Dokumentation:** `tests/README.md`
- **GitHub Actions Docs:** https://docs.github.com/actions
- **Coverage.py Docs:** https://coverage.readthedocs.io
- **Python unittest:** https://docs.python.org/3/library/unittest.html
## Zusammenfassung
**80 Tests**, alle bestanden (100% Erfolgsrate)
**GitHub Actions** für automatische Tests
**Coverage Reports** mit HTML-Visualisierung
**Pre-commit Hooks** für lokale Validierung
**Multi-Python-Version** Support (3.9-3.12)
**Code Quality** Checks mit flake8
Die Test-Suite ist **produktionsbereit** und vollständig in CI/CD integriert! 🎉

View file

@ -197,34 +197,83 @@ Die Statistik-Seite (`/statistics`) bietet:
- **Datenexport**: CSV und JSON-Download Ihrer Statistiken
- **Verlaufsanalyse**: Sehen Sie Ihre Fortschritte über mehrere Sitzungen
## 🧪 Tests
## 🧪 Tests & CI/CD
Das Projekt enthält umfangreiche Test-Suites:
Das Projekt enthält eine umfassende Test-Suite mit **80 Tests** (100% Erfolgsrate) und vollständiger CI/CD-Integration.
### App-Tests (18 Tests)
### Test-Übersicht
| Kategorie | Anzahl | Ausführungszeit | Status |
|-----------|--------|-----------------|--------|
| **Gesamt** | 80 Tests | ~2.9s | ✅ 100% |
| **Unit Tests** | 54 Tests | 0.002s ⚡ | ✅ Bestanden |
| **Integration Tests** | 26 Tests | 2.856s | ✅ Bestanden |
| **Legacy Tests** | 40 Tests | ~1s | ✅ Bestanden |
### Test-Ausführung
**Service Layer Tests (80 Tests):**
```bash
python -m unittest test_app -v
# Alle Tests (Unit + Integration)
python -m unittest discover -s tests -p "test_*.py" -v
# Nur Unit Tests (schnell, ohne DB)
python -m unittest tests.test_lesson_service tests.test_statistics_service tests.test_settings_service -v
# Nur Integration Tests (mit DB)
python -m unittest tests.test_integration_progress tests.test_integration_statistics -v
# Coverage Report generieren
./run_coverage.sh
```
Testet:
- Statistik-Berechnungen
- API-Endpoints
- Input-Validierung
- Datenbank-Operationen
- CSV/JSON-Export
### Metronom-Tests (22 Tests)
**Legacy Tests (40 Tests):**
```bash
# App-Tests (18 Tests)
python -m unittest test_app -v
# Metronom-Tests (22 Tests)
python test_metronome_velocity.py
```
Testet:
- Alle 5 Anpassungsregeln
- Realistische Szenarien (Anfänger bis Experte)
- Edge Cases und Grenzfälle
- Enthält detaillierte Simulation
### Was wird getestet?
Siehe [`README_METRONOME_TESTS.md`](README_METRONOME_TESTS.md) für Details.
**Service Layer Tests (`tests/`):**
- ✅ **LessonService** (17): Navigation, Validierung, Edge Cases
- ✅ **StatisticsService** (29): Berechnungen (ZPM/WPM), DB-Operationen, 30-Tage-Daten
- ✅ **SettingsService** (22): Validierungen, Boundary Values
- ✅ **ProgressService** (12): CRUD, State Management, Multi-Lesson Independence
**Legacy Tests:**
- ✅ **App-Tests**: Statistik-Berechnungen, API-Endpoints, Input-Validierung, CSV/JSON-Export
- ✅ **Metronom-Tests**: 5 Anpassungsregeln, Realistische Szenarien, Edge Cases
### CI/CD Integration
**GitHub Actions Workflows:**
![Tests](https://github.com/jamulix/typewriter/actions/workflows/tests.yml/badge.svg)
![Coverage](https://github.com/jamulix/typewriter/actions/workflows/coverage.yml/badge.svg)
- ✅ **Automatische Tests** bei jedem Push und Pull Request
- ✅ **Multi-Python-Version** Support (3.9, 3.10, 3.11, 3.12)
- ✅ **Coverage Reports** mit HTML-Visualisierung
- ✅ **Pre-commit Hooks** für lokale Validierung
- ✅ **Code Quality Checks** (flake8 Linting)
**Pre-commit Hook Installation:**
```bash
# Hook ist bereits installiert, oder kopiere Template:
cp .githooks/pre-commit .git/hooks/pre-commit
chmod +x .git/hooks/pre-commit
```
Der Pre-commit Hook führt automatisch alle Tests vor jedem Commit aus und blockiert bei Fehlern.
**Weitere Informationen:**
- 📖 Service Tests: [`tests/README.md`](tests/README.md)
- 📖 CI/CD Setup: [`CI_CD.md`](CI_CD.md)
- 📖 Metronom Tests: [`README_METRONOME_TESTS.md`](README_METRONOME_TESTS.md)
## 🔧 Entwicklung

32
run_coverage.sh Executable file
View file

@ -0,0 +1,32 @@
#!/bin/bash
# Generate Test Coverage Report
echo "📊 Generating Test Coverage Report..."
echo ""
# Check if coverage is installed
if ! command -v coverage &> /dev/null; then
echo "❌ Coverage not installed. Installing..."
pip install coverage
fi
# Run tests with coverage
echo "🧪 Running tests with coverage..."
coverage run -m unittest discover -s tests -p "test_*.py"
echo ""
echo "📈 Coverage Report:"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
coverage report -m
# Generate HTML report
echo ""
echo "🌐 Generating HTML report..."
coverage html
echo ""
echo "✅ Done!"
echo ""
echo "📁 HTML report generated in: htmlcov/"
echo " Open htmlcov/index.html in your browser to view detailed coverage."
echo ""