Files
klangkiste/docs/acceptance-tests.md
T
2026-01-14 13:11:07 +00:00

12 KiB
Raw Blame History

Acceptance-Tests

Zweck

Konsistenter Testkatalog basierend auf dem aktuellen Code. Alle Tests trennen Simulation und Hardware. Nicht implementierte Punkte sind explizit markiert.

Voraussetzungen

  • Repo-Root
  • Python 3
  • Box API fuer Simulation: python3 box/main.py run
  • GUI optional: cd gui/frontend && npm run dev
  • Backend optional: cd gui/backend && npm run dev

Hinweis:

  • Sobald die Box gepairt ist, erfordern /command Aufrufe den Header X-API-Token.

Schritt-fuer-Schritt

Die Tests koennen einzeln oder der Reihe nach ausgefuehrt werden.


Lokale Box-Tests (L1-L10)

Test L1: Box-Start & box_id

  1. Ziel
  • box_id wird einmalig erzeugt und bleibt stabil.
  1. Voraussetzungen
  • Simulation: box/data/box.json kann fehlen.
  • Hardware: frischer Start.
  1. Durchfuehrung Simulation / Emulation
  • Box starten:
python3 box/main.py run
  • Status lesen:
curl http://127.0.0.1:8000/status
  • Datei pruefen:
cat box/data/box.json
  1. Durchfuehrung Reale Box (Hardware)
  • Box einschalten.
  • Statusseite/API pruefen (sofern erreichbar).
  1. Erwartetes Ergebnis
  • box_id im Format klangkiste-<10 chars a-z0-9>.
  • box/data/box.json bleibt stabil ueber Neustarts.
  1. Abweichungen / Fehlersuche
  • box_id fehlt: Schreibrechte in box/data/ pruefen.

Test L2: WLAN-Ersteinrichtung (Setup WebGUI)

  1. Ziel
  • WLAN-Profil per Setup UI anlegen.
  1. Voraussetzungen
  • Keine WLAN-Profile gespeichert.
  1. Durchfuehrung Simulation / Emulation
  • WLAN reset:
curl -X POST http://127.0.0.1:8000/command \
  -H "Content-Type: application/json" \
  -d '{"command":"wifi_reset"}'
  • Setup UI oeffnen:
http://127.0.0.1:9000/setup
  • SSID waehlen, Passwort eingeben, speichern.
  • Status pruefen:
curl http://127.0.0.1:8000/status
  1. Durchfuehrung Reale Box (Hardware)
  • Nicht testbar mit aktuellem Code: kein echter AP/WLAN-Stack.
  1. Erwartetes Ergebnis
  • wifi_state = WIFI_ONLINE
  • connected_ssid gesetzt
  1. Abweichungen / Fehlersuche
  • Setup UI nicht erreichbar: Port 9000 frei, Box laeuft.

Test L3: Persistenz & Neustart

  1. Ziel
  • Resume und WLAN-Profile bleiben ueber Neustart erhalten.
  1. Voraussetzungen
  • WLAN-Profil vorhanden.
  • Playback einmal gestartet.
  1. Durchfuehrung Simulation / Emulation
  • WLAN-Profil setzen:
curl -X POST http://127.0.0.1:8000/command \
  -H "Content-Type: application/json" \
  -d '{"command":"wifi_add_profile","payload":{"ssid":"HomeWiFi","password":"secret","priority":10}}'
  • Playback starten:
curl -X POST http://127.0.0.1:8000/command \
  -H "Content-Type: application/json" \
  -d '{"command":"nfc_on","payload":{"uid":"UID_1"}}'
  • Playback stoppen:
curl -X POST http://127.0.0.1:8000/command \
  -H "Content-Type: application/json" \
  -d '{"command":"nfc_off","payload":{"uid":"UID_1"}}'
  • Box-Prozess neu starten.
  • Status pruefen:
curl http://127.0.0.1:8000/status
  1. Durchfuehrung Reale Box (Hardware)
  • Nicht testbar mit aktuellem Code: kein echter WLAN-Stack.
  1. Erwartetes Ergebnis
  • box/data/state.json enthaelt Resume.
  • box/data/secrets.enc existiert.
  1. Abweichungen / Fehlersuche
  • Resume fehlt: box/data/state.json pruefen.

Test L4: HTTP API Status & Commands

  1. Ziel
  • /status und /command liefern Antworten und aendern Status.
  1. Voraussetzungen
  • Box laeuft.
  1. Durchfuehrung Simulation / Emulation
  • Status:
curl http://127.0.0.1:8000/status
  • Command (vor Pairing -> 403 erwartet):
curl -X POST http://127.0.0.1:8000/command \
  -H "Content-Type: application/json" \
  -d '{"command":"play_pause"}'
  1. Durchfuehrung Reale Box (Hardware)
  • Gleich wie Simulation, sofern API erreichbar.
  1. Erwartetes Ergebnis
  • Vor Pairing: HTTP 403 fuer gesperrte Commands.
  • Nach Pairing (mit Token): HTTP 200 und Status aktualisiert.
  1. Abweichungen / Fehlersuche
  • 400: Payload pruefen.

Test L5: GUI-Steuerung

  1. Ziel
  • GUI steuert Box und zeigt Live-Status.
  1. Voraussetzungen
  • GUI laeuft auf 127.0.0.1:5174.
  1. Durchfuehrung Simulation / Emulation
  • GUI oeffnen, Buttons klicken.
  • Status aendert sich innerhalb von 1s.
  1. Durchfuehrung Reale Box (Hardware)
  • GUI auf Box-IP ausrichten (spaeter).
  1. Erwartetes Ergebnis
  • /status aendert sich nach Commands.
  1. Abweichungen / Fehlersuche
  • GUI "Failed to fetch": VITE_BACKEND_URL pruefen.

Test L6: Playback & NFC

  1. Ziel
  • NFC startet Playback.
  1. Voraussetzungen
  • Tags in box/data/box.json.
  • Medien im Backend unter gui/backend/media.
  1. Durchfuehrung Simulation / Emulation
curl -X POST http://127.0.0.1:8000/command \
  -H "Content-Type: application/json" \
  -d '{"command":"nfc_on","payload":{"uid":"UID_1"}}'
  1. Durchfuehrung Reale Box (Hardware)
  • NFC-Tag auflegen (spaeter).
  1. Erwartetes Ergebnis
  • playback_state.state = PLAYING
  1. Abweichungen / Fehlersuche
  • Tag fehlt: box/data/box.json pruefen.

Test L7: Resume-Logik

  1. Ziel
  • Resume pro UID funktioniert.
  1. Voraussetzungen
  • Playback einmal gestartet.
  1. Durchfuehrung Simulation / Emulation
  • nfc_on UID_1, warten, nfc_off UID_1, dann nfc_on UID_1.
  1. Durchfuehrung Reale Box (Hardware)
  • NFC auflegen/abnehmen (spaeter).
  1. Erwartetes Ergebnis
  • Resume nutzt gespeicherte Position.
  1. Abweichungen / Fehlersuche
  • Resume = 0: box/data/state.json pruefen.

Test L8: Rekursion & Ordnerstruktur

  1. Ziel
  • Rekursive Reihenfolge (DFS) ist korrekt.
  1. Voraussetzungen
  • Verschachtelte Ordner im Backend unter gui/backend/media.
  1. Durchfuehrung Simulation / Emulation
  • Tag auf media/book_6 setzen, nfc_on.
  1. Durchfuehrung Reale Box (Hardware)
  • Medienstruktur auf Box kopieren (spaeter).
  1. Erwartetes Ergebnis
  • DFS-Reihenfolge, lexikografisch.
  1. Abweichungen / Fehlersuche
  • Reihenfolge falsch: Ordnernamen pruefen.

Test L9: Offline-Szenarien (Box intern)

  1. Ziel
  • WiFi/Spotify-Status reagieren auf Commands.
  1. Voraussetzungen
  • Box laeuft.
  1. Durchfuehrung Simulation / Emulation
  • wifi_reset und spotify_clear ausfuehren.
  1. Durchfuehrung Reale Box (Hardware)
  • Nicht testbar mit aktuellem Code.
  1. Erwartetes Ergebnis
  • wifi_state = WIFI_UNCONFIGURED
  • spotify_status = NOT_CONFIGURED
  1. Abweichungen / Fehlersuche
  • Status aendert sich nicht: /status pruefen.

Test L10: Fehlerfaelle (Box intern)

  1. Ziel
  • Fehler setzen last_error.
  1. Voraussetzungen
  • Box laeuft.
  1. Durchfuehrung Simulation / Emulation
curl -X POST http://127.0.0.1:8000/command \
  -H "Content-Type: application/json" \
  -d '{"command":"trigger_error","payload":{"type":"uid_unmapped"}}'
  1. Durchfuehrung Reale Box (Hardware)
  • Nicht testbar mit aktuellem Code.
  1. Erwartetes Ergebnis
  • playback_state.last_error gesetzt.
  1. Abweichungen / Fehlersuche
  • Kein Fehler sichtbar: /status pruefen.

Backend/Pairing-Tests (A-J)

Test A: Box-Erststart & Identitaet

  1. Ziel
  • box_id wird einmalig erzeugt.
  1. Voraussetzungen
  • Box gestartet.
  1. Durchfuehrung Simulation / Emulation
  • Siehe Test L1.
  1. Durchfuehrung Reale Box (Hardware)
  • Siehe Test L1.
  1. Erwartetes Ergebnis
  • box_id stabil.
  1. Abweichungen / Fehlersuche
  • Siehe Test L1.

Test B: Announce -> neue Box erscheint im Backend

  1. Ziel
  • Box meldet sich beim Backend und erscheint als UNPAIRED.
  1. Voraussetzungen
  • Backend laeuft:
cd gui/backend
npm run dev
  • Frontend laeuft:
cd gui/frontend
npm run dev -- --host 0.0.0.0 --port 5174 --strictPort
  1. Durchfuehrung Simulation / Emulation
  • Box starten:
python3 box/main.py run
  • 30-60s warten (Announce-Intervall).
  • Frontend-GUI oeffnen:
http://127.0.0.1:5174
  • Optional: Backend-Storage pruefen:
sqlite3 gui/backend/db/klangkiste.sqlite "SELECT box_id, state, last_seen FROM boxes;"
  1. Durchfuehrung Reale Box (Hardware)
  • Box einschalten.
  • Frontend-GUI oeffnen, Box sollte erscheinen.
  1. Erwartetes Ergebnis
  • Box erscheint als UNPAIRED in der Frontend-GUI.
  • gui/backend/db/klangkiste.sqlite enthaelt box_id und fingerprint.
  1. Abweichungen / Fehlersuche
  • Keine Box sichtbar: Backend-URL in box/data/box.json pruefen.
  • Backend nicht erreichbar: Backend-Prozess/Port 5001 pruefen.

Test C: Mehrere Boxen gleichzeitig

  1. Ziel
  • Mehrere Boxen werden separat erkannt.
  1. Voraussetzungen
  • Mehrere Boxen mit unterschiedlichen box_id.
  1. Durchfuehrung Simulation / Emulation
  • Nicht testbar mit aktuellem Code: Box nutzt festen box/data/-Pfad und kann nicht mehrfach parallel laufen.
  1. Durchfuehrung Reale Box (Hardware)
  • Zwei physische Boxen einschalten.
  • Frontend-GUI zeigt beide UNPAIRED an.
  1. Erwartetes Ergebnis
  • Zwei Eintraege mit unterschiedlichen box_id.
  1. Abweichungen / Fehlersuche
  • Duplikate: box_id doppelt? Factory-Reset pruefen.

Test D: Pairing-Freigabe ueber Frontend-GUI

  1. Ziel
  • Pairing liefert API-Token und Box wird PAIRED.
  1. Voraussetzungen
  • Box erscheint als UNPAIRED in der Frontend-GUI.
  1. Durchfuehrung Simulation / Emulation
  • Frontend-GUI oeffnen:
http://127.0.0.1:5174
  • Button "Pairen" klicken.
  • API-Token via Backend-API abrufen:
curl -X POST http://127.0.0.1:5001/api/boxes/pair   -H "Content-Type: application/json"   -d '{"box_id":"<box_id>"}'
  1. Durchfuehrung Reale Box (Hardware)
  • Gleiches Vorgehen ueber Frontend-GUI.
  1. Erwartetes Ergebnis
  • Box erscheint in der gepaarten Liste.
  • api_token wird an die Box ausgeliefert.
  1. Abweichungen / Fehlersuche
  • Pairing bleibt aus: gui/backend/db/klangkiste.sqlite pruefen.

Test E: Verhalten vor Pairing (keine Steuerung erlaubt)

  1. Ziel
  • Vor Pairing werden Steuerbefehle blockiert.
  1. Voraussetzungen
  • Box UNPAIRED.
  1. Durchfuehrung Simulation / Emulation
curl -i -X POST http://127.0.0.1:8000/command   -H "Content-Type: application/json"   -d '{"command":"play_pause"}'
  1. Durchfuehrung Reale Box (Hardware)
  • Gleicher Request gegen Box-IP.
  1. Erwartetes Ergebnis
  • HTTP 403 "pairing required".
  1. Abweichungen / Fehlersuche
  • Wenn 200: Pairing-Status und API-Token pruefen.

Test F: Verhalten nach Pairing

  1. Ziel
  • Nach Pairing sind Commands erlaubt (mit Token).
  1. Voraussetzungen
  • Box PAIRED und api_token vorhanden.
  1. Durchfuehrung Simulation / Emulation
curl -i -X POST http://127.0.0.1:8000/command   -H "Content-Type: application/json"   -H "X-API-Token: <api_token>"   -d '{"command":"play_pause"}'
  1. Durchfuehrung Reale Box (Hardware)
  • Gleiches Vorgehen gegen Box-IP.
  1. Erwartetes Ergebnis
  • HTTP 200, Status aktualisiert.
  1. Abweichungen / Fehlersuche
  • 403: Token pruefen, Pairing-Status pruefen.

Test G: Neustart vor/nach Pairing

  1. Ziel
  • Pairing-Status und Token bleiben ueber Neustart erhalten.
  1. Voraussetzungen
  • Box PAIRED.
  1. Durchfuehrung Simulation / Emulation
  • Box-Prozess stoppen, neu starten.
  • Mit Token Command senden.
  1. Durchfuehrung Reale Box (Hardware)
  • Power cycle.
  1. Erwartetes Ergebnis
  • Box bleibt PAIRED, Token weiterhin gueltig.
  1. Abweichungen / Fehlersuche
  • Token fehlt: box/data/secrets.enc pruefen.

Test H: Factory Reset -> neue Identitaet

  1. Ziel
  • Factory Reset erzeugt neue Identitaet.
  1. Voraussetzungen
  • Box einmal gestartet.
  1. Durchfuehrung Simulation / Emulation
  • Box stoppen.
  • Dateien loeschen:
rm -f box/data/box.json box/data/state.json box/data/secrets.enc
  • Box neu starten.
  1. Durchfuehrung Reale Box (Hardware)
  • Nicht testbar mit aktuellem Code: kein Reset-Mechanismus.
  1. Erwartetes Ergebnis
  • Neue box_id.
  1. Abweichungen / Fehlersuche
  • box_id bleibt gleich: Dateien nicht geloescht.

Test I: Offline / Backend nicht erreichbar

  1. Ziel
  • Box laeuft weiter ohne Backend.
  1. Voraussetzungen
  • Box laeuft, Backend gestoppt.
  1. Durchfuehrung Simulation / Emulation
  • Backend stoppen.
  • Playback starten (mit Token falls gepairt).
  1. Durchfuehrung Reale Box (Hardware)
  • Backend vom Netz trennen.
  1. Erwartetes Ergebnis
  • Lokale Playback-Logik laeuft weiter.
  • Nicht testbar mit aktuellem Code: Backend markiert OFFLINE nicht.
  1. Abweichungen / Fehlersuche
  • Box stoppt: lokale Logs pruefen.

Test J: Simulation vs. Hardware Unterschiede

  1. Ziel
  • Unterschiede klar dokumentieren.
  1. Voraussetzungen
  • Box laeuft in Simulation.
  1. Durchfuehrung Simulation / Emulation
  • WiFi/IP/Spotify/Audio sind Mock.
  • Setup UI und API funktionieren lokal.
  1. Durchfuehrung Reale Box (Hardware)
  • Echte Backends notwendig (nicht implementiert).
  1. Erwartetes Ergebnis
  • Simulation laeuft ohne Hardware.
  1. Abweichungen / Fehlersuche
  • Hardware-Backends fehlen.