Kern-Review-Agent

Test-Analyst

Stellt sicher, dass Ihre Tests Sie wirklich schützen

Bestandene Tests bedeuten nicht, dass Ihr Code funktioniert. Test-Analyst findet die Lücken — fehlende Edge Cases, instabile Tests und Isolationsprobleme, die Bugs durchlassen.

Was Test-Analyst erkennt

Die Lücken in Ihrer Test-Suite, die Bugs entkommen lassen

Fehlende Edge-Case-Abdeckung

Der Happy Path ist getestet, aber was ist mit Nullwerten, leeren Arrays und Grenzwerten?

Null-EingabenLeere CollectionsGrenzwerteFehlerpfade

Instabile Tests

Tests, die manchmal bestehen und manchmal nicht — die stillen Killer des CI/CD-Vertrauens

Timing-AbhängigkeitenReihenfolge-AbhängigkeitenGemeinsamer StateNetzwerk-Aufrufe

Schlechte Test-Isolation

Tests, die voneinander abhängig sind oder veränderbaren State teilen — Debugging-Albträume

Gemeinsame FixturesDatenbank-VerschmutzungGlobaler StateTest-Reihenfolge-Bugs

Alle Testarten abgedeckt

Von Unit-Tests bis E2E, Test-Analyst überprüft sie alle

Unit-Tests

Testen auf Funktions- und Klassenebene

Integrationstests

Testen der Komponenteninteraktion

E2E-Tests

End-to-End-Benutzerflusstests

API-Tests

Endpoint- und Vertragstests

Snapshot-Tests

UI-Regressionserkennung

Performance-Tests

Last- und Benchmark-Tests

Verbesserung der Testqualität

Echte Beispiele für Testverbesserungen

Fehlender Edge Case

Schwacher Test
describe('calculateDiscount', () => {
  it('wendet 10% für Bestellungen über 100€ an', () => {
    expect(calculateDiscount(150)).toBe(15)
  })

  it('wendet 5% für Bestellungen über 50€ an', () => {
    expect(calculateDiscount(75)).toBe(3.75)
  })

  // Was ist mit 0€? Negativ? Genau 50€? 100€?
})

Fehlende Grenzwert-Tests: 0€, 50€, 100€, negativ

Starker Test
describe('calculateDiscount', () => {
  it('wendet 10% für Bestellungen über 100€ an', () => {
    expect(calculateDiscount(150)).toBe(15)
  })

  it('wendet 5% für Bestellungen über 50€ an', () => {
    expect(calculateDiscount(75)).toBe(3.75)
  })

  it('gibt 0 für Bestellungen an der Grenze zurück', () => {
    expect(calculateDiscount(50)).toBe(0)
    expect(calculateDiscount(100)).toBe(5) // 5% Stufe
  })

  it('behandelt Null und Negativ ordnungsgemäß', () => {
    expect(calculateDiscount(0)).toBe(0)
    expect(calculateDiscount(-10)).toBe(0)
  })
})

Edge Cases für Grenzwerte und ungültige Eingaben hinzufügen

Instabiler Test-Erkennung

Schwacher Test
it('zeigt Benachrichtigung nach Speichern', async () => {
  await user.click(saveButton)

  // Instabil! Abhängig vom Timing
  await waitFor(() => {
    expect(screen.getByText('Gespeichert!')).toBeVisible()
  })

  // Noch schlimmer: willkürliches Timeout
  await new Promise(r => setTimeout(r, 100))
  expect(notificationCount).toBe(1)
})

Willkürliche Timeouts und Timing-Annahmen

Starker Test
it('zeigt Benachrichtigung nach Speichern', async () => {
  await user.click(saveButton)

  // Warte auf spezifische Zustandsänderung
  await waitFor(() => {
    expect(screen.getByRole('alert')).toHaveTextContent('Gespeichert!')
  })

  // Behauptung auf beobachtbares Verhalten, nicht Timing
  expect(
    await screen.findByRole('alert', { name: /gespeichert/i })
  ).toBeVisible()
})

Auf beobachtbare Zustandsänderungen warten, nicht auf Zeit

Test-Isolationsproblem

Schwacher Test
let testUser: User

beforeAll(async () => {
  // Gemeinsam für ALLE Tests — Mutationen sickern durch!
  testUser = await createUser({ name: 'Test' })
})

it('aktualisiert Benutzernamen', async () => {
  await updateUser(testUser.id, { name: 'Aktualisiert' })
  // Jetzt ist testUser.name 'Aktualisiert' für alle folgenden Tests
})

it('prüft ursprünglichen Namen', () => {
  // FEHLER! Vorheriger Test hat gemeinsamen State mutiert
  expect(testUser.name).toBe('Test')
})

Gemeinsamer State in beforeAll sickert zwischen Tests durch

Starker Test
describe('Benutzeraktualisierungen', () => {
  let testUser: User

  beforeEach(async () => {
    // Frischer Benutzer für JEDEN Test
    testUser = await createUser({ name: 'Test' })
  })

  afterEach(async () => {
    await deleteUser(testUser.id)
  })

  it('aktualisiert Benutzernamen', async () => {
    await updateUser(testUser.id, { name: 'Aktualisiert' })
    expect(testUser.name).toBe('Aktualisiert')
  })

  it('prüft ursprünglichen Namen', () => {
    // Funktioniert! Frischer testUser mit ursprünglichem Namen
    expect(testUser.name).toBe('Test')
  })
})

beforeEach für Test-Isolation verwenden

Test-Analyse

So funktioniert Test-Analyst

Test-Analyst zählt nicht nur Tests — er analysiert, was sie tatsächlich testen. Er findet die Lücken zwischen dem, was Ihre Tests abdecken, und dem, was Ihr Code benötigt.

Pfadanalyse

Ordnet Code-Pfade zu, um ungetestete Verzweigungen zu finden

Instabilitätserkennung

Identifiziert Timing- und Reihenfolge-Abhängigkeiten

Edge-Case-Vorschläge

Empfiehlt spezifische hinzuzufügende Testfälle

Analyse-Pipeline

1

Test-Abdeckung analysieren

Ermittelt, welche Code-Pfade getestet sind und welche nicht

2

Schwachstellen identifizieren

Findet Edge Cases und Fehlerbedingungen ohne Tests

3

Anti-Patterns erkennen

Erkennt instabile Muster und Isolationsprobleme

4

Verbesserungen vorschlagen

Empfiehlt spezifische hinzuzufügende Testfälle

Warum Testqualität wichtig ist

Schlechte Tests sind schlimmer als keine Tests — sie geben falsches Vertrauen

Echte Bugs fangen

Tests, die Edge Cases abdecken, fangen Bugs, bevor es Benutzer tun

Zuverlässiges CI/CD

Kein "Wiederholen bis grün" mehr — Tests bestehen oder scheitern aus echten Gründen

Sicher refactorn

Gute Tests erlauben es Ihnen, Code mit Zuversicht zu ändern

100% Abdeckung bedeutet nichts, wenn Tests keine Bugs fangen.
Test-Analyst stellt sicher, dass Ihre Tests tatsächlich funktionieren.

Tests, die Sie tatsächlich
schützen

Lassen Sie Test-Analyst die Lücken in Ihrer Test-Suite finden. 14 Tage kostenlos, keine Kreditkarte erforderlich.

Edge-Case-Erkennung
Instabile Test-Prävention
Isolationsanalyse