Files
breakpilot-compliance/docs-src/development/testing.md
Benjamin Admin 2ed1c08acf
All checks were successful
CI/CD / go-lint (push) Has been skipped
CI/CD / python-lint (push) Has been skipped
CI/CD / nodejs-lint (push) Has been skipped
CI/CD / test-go-ai-compliance (push) Successful in 32s
CI/CD / test-python-backend-compliance (push) Successful in 31s
CI/CD / test-python-document-crawler (push) Successful in 23s
CI/CD / test-python-dsms-gateway (push) Successful in 17s
CI/CD / validate-canonical-controls (push) Successful in 12s
CI/CD / Deploy (push) Successful in 2s
feat: enhance legal basis display, add batch processing tests and docs
- Backfill 81 controls with empty source_citation.source from generation_metadata
- Add fallback to generation_metadata.source_regulation in ControlDetail blue box
- Improve Rule 3 amber box text for reformulated controls
- Add 30 new tests for batch processing (TestParseJsonArray, TestBatchSizeConfig,
  TestBatchProcessingLoop) — all 61 control generator tests passing
- Fix stale test_config_defaults assertion (max_controls 50→0)
- Update canonical-control-library.md with batch processing pipeline docs,
  processed chunks tracking, migration guide, and stats endpoint
- Update testing.md with canonical control generator test section

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-14 23:51:52 +01:00

6.1 KiB

Test-Regeln

Automatische Test-Erweiterung

WICHTIG: Bei JEDER Code-Aenderung muessen entsprechende Tests erstellt oder aktualisiert werden!

Wann Tests schreiben?

IMMER wenn du:

  1. Neue Funktionen erstellst → Unit Test
  2. Neue API-Endpoints hinzufuegst → Handler Test
  3. Bugs fixst → Regression Test (der Bug sollte nie wieder auftreten)
  4. Bestehenden Code aenderst → Bestehende Tests anpassen

Test-Struktur

Speicherort: Im gleichen Verzeichnis wie der Code

internal/
├── services/
│   ├── auth_service.go
│   └── auth_service_test.go    ← Test hier
├── handlers/
│   ├── handlers.go
│   └── handlers_test.go        ← Test hier
└── middleware/
    ├── auth.go
    └── middleware_test.go      ← Test hier

Test-Namenskonvention:

func TestFunctionName_Scenario_ExpectedResult(t *testing.T)

// Beispiele:
func TestHashPassword_ValidPassword_ReturnsHash(t *testing.T)
func TestLogin_InvalidCredentials_Returns401(t *testing.T)
func TestCreateDocument_MissingTitle_ReturnsError(t *testing.T)

Test-Template:

func TestFunctionName(t *testing.T) {
    // Arrange
    service := &MyService{}
    input := "test-input"

    // Act
    result, err := service.DoSomething(input)

    // Assert
    if err != nil {
        t.Fatalf("Expected no error, got %v", err)
    }
    if result != expected {
        t.Errorf("Expected %v, got %v", expected, result)
    }
}

Table-Driven Tests bevorzugen:

func TestValidateEmail(t *testing.T) {
    tests := []struct {
        name     string
        email    string
        expected bool
    }{
        {"valid email", "test@example.com", true},
        {"missing @", "testexample.com", false},
        {"empty", "", false},
    }

    for _, tt := range tests {
        t.Run(tt.name, func(t *testing.T) {
            result := ValidateEmail(tt.email)
            if result != tt.expected {
                t.Errorf("Expected %v, got %v", tt.expected, result)
            }
        })
    }
}

Python Tests (Backend)

Speicherort: /backend/tests/

backend/
├── consent_client.py
├── gdpr_api.py
└── tests/
    ├── __init__.py
    ├── test_consent_client.py  ← Tests fuer consent_client.py
    └── test_gdpr_api.py        ← Tests fuer gdpr_api.py

Test-Namenskonvention:

class TestClassName:
    def test_method_scenario_expected_result(self):
        pass

# Beispiele:
class TestConsentClient:
    def test_check_consent_valid_token_returns_status(self):
        pass

    def test_check_consent_expired_token_raises_error(self):
        pass

Test-Template:

import pytest
from unittest.mock import AsyncMock, patch, MagicMock

class TestMyFeature:
    def test_sync_function(self):
        # Arrange
        input_data = "test"

        # Act
        result = my_function(input_data)

        # Assert
        assert result == expected

    @pytest.mark.asyncio
    async def test_async_function(self):
        # Arrange
        client = MyClient()

        # Act
        with patch("httpx.AsyncClient") as mock:
            mock_instance = AsyncMock()
            mock.return_value = mock_instance
            result = await client.fetch_data()

        # Assert
        assert result is not None

Test-Kategorien

1. Unit Tests (Hoechste Prioritaet)

  • Testen einzelne Funktionen/Methoden
  • Keine externen Abhaengigkeiten (Mocks verwenden)
  • Schnell ausfuehrbar

2. Integration Tests

  • Testen Zusammenspiel mehrerer Komponenten
  • Koennen echte DB verwenden (Test-DB)

3. Security Tests

  • Auth/JWT Validierung
  • Passwort-Hashing
  • Berechtigungspruefung

Checkliste vor Abschluss

Vor dem Abschluss einer Aufgabe:

  • Gibt es Tests fuer alle neuen Funktionen?
  • Gibt es Tests fuer alle Edge Cases?
  • Gibt es Tests fuer Fehlerfaelle?
  • Laufen alle bestehenden Tests noch? (go test ./... / pytest)
  • Ist die Test-Coverage angemessen?

Tests ausfuehren

# Go - Alle Tests
cd consent-service && go test -v ./...

# Go - Mit Coverage
cd consent-service && go test -cover ./...

# Python - Alle Tests
cd backend && source venv/bin/activate && pytest -v

# Python - Mit Coverage
cd backend && pytest --cov=. --cov-report=html

Beispiel: Vollstaendiger Test-Workflow

Wenn du z.B. eine neue GetUserStats() Funktion im Go Service hinzufuegst:

  1. Funktion schreiben in internal/services/stats_service.go
  2. Test erstellen in internal/services/stats_service_test.go:
    func TestGetUserStats_ValidUser_ReturnsStats(t *testing.T) {...}
    func TestGetUserStats_InvalidUser_ReturnsError(t *testing.T) {...}
    func TestGetUserStats_NoConsents_ReturnsEmptyStats(t *testing.T) {...}
    
  3. Tests ausfuehren: go test -v ./internal/services/...
  4. Dokumentation aktualisieren (siehe Dokumentation)

Modul-spezifische Tests

Canonical Control Generator (82 Tests)

Die Control Library hat eine umfangreiche Test-Suite ueber 6 Dateien. Siehe Canonical Control Library — Tests fuer Details.

# Alle Generator-Tests
cd backend-compliance && pytest -v tests/test_control_generator.py

# Similarity Detector Tests
cd backend-compliance && pytest -v compliance/tests/test_similarity_detector.py

# API Route Tests
cd backend-compliance && pytest -v tests/test_canonical_control_routes.py

# License Gate Tests
cd backend-compliance && pytest -v tests/test_license_gate.py

# CI/CD Validator Tests
cd backend-compliance && pytest -v tests/test_validate_controls.py

Wichtig: Die Generator-Tests nutzen Mocks fuer Anthropic-API und Qdrant — sie laufen ohne externe Abhaengigkeiten. Die TestPipelineMocked-Klasse prueft insbesondere:

  • Korrekte Lizenz-Klassifikation (Rule 1/2/3 Verhalten)
  • Rule 3 exponiert keine Quellennamen in generation_metadata
  • SHA-256 Hash-Deduplizierung fuer Chunks
  • Config-Defaults (batch_size: 5, skip_processed: true)
  • Rule 1 Citation wird korrekt mit Gesetzesreferenz generiert