12 KiB
12 KiB
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
/commandAufrufe den HeaderX-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
- Ziel
- box_id wird einmalig erzeugt und bleibt stabil.
- Voraussetzungen
- Simulation:
box/data/box.jsonkann fehlen. - Hardware: frischer Start.
- 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
- Durchfuehrung – Reale Box (Hardware)
- Box einschalten.
- Statusseite/API pruefen (sofern erreichbar).
- Erwartetes Ergebnis
box_idim Formatklangkiste-<10 chars a-z0-9>.box/data/box.jsonbleibt stabil ueber Neustarts.
- Abweichungen / Fehlersuche
box_idfehlt: Schreibrechte inbox/data/pruefen.
Test L2: WLAN-Ersteinrichtung (Setup WebGUI)
- Ziel
- WLAN-Profil per Setup UI anlegen.
- Voraussetzungen
- Keine WLAN-Profile gespeichert.
- 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
- Durchfuehrung – Reale Box (Hardware)
- Nicht testbar mit aktuellem Code: kein echter AP/WLAN-Stack.
- Erwartetes Ergebnis
wifi_state = WIFI_ONLINEconnected_ssidgesetzt
- Abweichungen / Fehlersuche
- Setup UI nicht erreichbar: Port 9000 frei, Box laeuft.
Test L3: Persistenz & Neustart
- Ziel
- Resume und WLAN-Profile bleiben ueber Neustart erhalten.
- Voraussetzungen
- WLAN-Profil vorhanden.
- Playback einmal gestartet.
- 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
- Durchfuehrung – Reale Box (Hardware)
- Nicht testbar mit aktuellem Code: kein echter WLAN-Stack.
- Erwartetes Ergebnis
box/data/state.jsonenthaelt Resume.box/data/secrets.encexistiert.
- Abweichungen / Fehlersuche
- Resume fehlt:
box/data/state.jsonpruefen.
Test L4: HTTP API Status & Commands
- Ziel
- /status und /command liefern Antworten und aendern Status.
- Voraussetzungen
- Box laeuft.
- 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"}'
- Durchfuehrung – Reale Box (Hardware)
- Gleich wie Simulation, sofern API erreichbar.
- Erwartetes Ergebnis
- Vor Pairing: HTTP 403 fuer gesperrte Commands.
- Nach Pairing (mit Token): HTTP 200 und Status aktualisiert.
- Abweichungen / Fehlersuche
- 400: Payload pruefen.
Test L5: GUI-Steuerung
- Ziel
- GUI steuert Box und zeigt Live-Status.
- Voraussetzungen
- GUI laeuft auf 127.0.0.1:5174.
- Durchfuehrung – Simulation / Emulation
- GUI oeffnen, Buttons klicken.
- Status aendert sich innerhalb von 1s.
- Durchfuehrung – Reale Box (Hardware)
- GUI auf Box-IP ausrichten (spaeter).
- Erwartetes Ergebnis
/statusaendert sich nach Commands.
- Abweichungen / Fehlersuche
- GUI "Failed to fetch":
VITE_BACKEND_URLpruefen.
Test L6: Playback & NFC
- Ziel
- NFC startet Playback.
- Voraussetzungen
- Tags in
box/data/box.json. - Medien im Backend unter
gui/backend/media.
- 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"}}'
- Durchfuehrung – Reale Box (Hardware)
- NFC-Tag auflegen (spaeter).
- Erwartetes Ergebnis
playback_state.state = PLAYING
- Abweichungen / Fehlersuche
- Tag fehlt:
box/data/box.jsonpruefen.
Test L7: Resume-Logik
- Ziel
- Resume pro UID funktioniert.
- Voraussetzungen
- Playback einmal gestartet.
- Durchfuehrung – Simulation / Emulation
nfc_on UID_1, warten,nfc_off UID_1, dannnfc_on UID_1.
- Durchfuehrung – Reale Box (Hardware)
- NFC auflegen/abnehmen (spaeter).
- Erwartetes Ergebnis
- Resume nutzt gespeicherte Position.
- Abweichungen / Fehlersuche
- Resume = 0:
box/data/state.jsonpruefen.
Test L8: Rekursion & Ordnerstruktur
- Ziel
- Rekursive Reihenfolge (DFS) ist korrekt.
- Voraussetzungen
- Verschachtelte Ordner im Backend unter
gui/backend/media.
- Durchfuehrung – Simulation / Emulation
- Tag auf
media/book_6setzen,nfc_on.
- Durchfuehrung – Reale Box (Hardware)
- Medienstruktur auf Box kopieren (spaeter).
- Erwartetes Ergebnis
- DFS-Reihenfolge, lexikografisch.
- Abweichungen / Fehlersuche
- Reihenfolge falsch: Ordnernamen pruefen.
Test L9: Offline-Szenarien (Box intern)
- Ziel
- WiFi/Spotify-Status reagieren auf Commands.
- Voraussetzungen
- Box laeuft.
- Durchfuehrung – Simulation / Emulation
wifi_resetundspotify_clearausfuehren.
- Durchfuehrung – Reale Box (Hardware)
- Nicht testbar mit aktuellem Code.
- Erwartetes Ergebnis
wifi_state = WIFI_UNCONFIGUREDspotify_status = NOT_CONFIGURED
- Abweichungen / Fehlersuche
- Status aendert sich nicht:
/statuspruefen.
Test L10: Fehlerfaelle (Box intern)
- Ziel
- Fehler setzen
last_error.
- Voraussetzungen
- Box laeuft.
- 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"}}'
- Durchfuehrung – Reale Box (Hardware)
- Nicht testbar mit aktuellem Code.
- Erwartetes Ergebnis
playback_state.last_errorgesetzt.
- Abweichungen / Fehlersuche
- Kein Fehler sichtbar:
/statuspruefen.
Backend/Pairing-Tests (A-J)
Test A: Box-Erststart & Identitaet
- Ziel
- box_id wird einmalig erzeugt.
- Voraussetzungen
- Box gestartet.
- Durchfuehrung – Simulation / Emulation
- Siehe Test L1.
- Durchfuehrung – Reale Box (Hardware)
- Siehe Test L1.
- Erwartetes Ergebnis
- box_id stabil.
- Abweichungen / Fehlersuche
- Siehe Test L1.
Test B: Announce -> neue Box erscheint im Backend
- Ziel
- Box meldet sich beim Backend und erscheint als UNPAIRED.
- 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
- 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;"
- Durchfuehrung – Reale Box (Hardware)
- Box einschalten.
- Frontend-GUI oeffnen, Box sollte erscheinen.
- Erwartetes Ergebnis
- Box erscheint als UNPAIRED in der Frontend-GUI.
gui/backend/db/klangkiste.sqliteenthaeltbox_idundfingerprint.
- Abweichungen / Fehlersuche
- Keine Box sichtbar: Backend-URL in
box/data/box.jsonpruefen. - Backend nicht erreichbar: Backend-Prozess/Port 5001 pruefen.
Test C: Mehrere Boxen gleichzeitig
- Ziel
- Mehrere Boxen werden separat erkannt.
- Voraussetzungen
- Mehrere Boxen mit unterschiedlichen
box_id.
- Durchfuehrung – Simulation / Emulation
- Nicht testbar mit aktuellem Code: Box nutzt festen
box/data/-Pfad und kann nicht mehrfach parallel laufen.
- Durchfuehrung – Reale Box (Hardware)
- Zwei physische Boxen einschalten.
- Frontend-GUI zeigt beide UNPAIRED an.
- Erwartetes Ergebnis
- Zwei Eintraege mit unterschiedlichen
box_id.
- Abweichungen / Fehlersuche
- Duplikate:
box_iddoppelt? Factory-Reset pruefen.
Test D: Pairing-Freigabe ueber Frontend-GUI
- Ziel
- Pairing liefert API-Token und Box wird PAIRED.
- Voraussetzungen
- Box erscheint als UNPAIRED in der Frontend-GUI.
- 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>"}'
- Durchfuehrung – Reale Box (Hardware)
- Gleiches Vorgehen ueber Frontend-GUI.
- Erwartetes Ergebnis
- Box erscheint in der gepaarten Liste.
api_tokenwird an die Box ausgeliefert.
- Abweichungen / Fehlersuche
- Pairing bleibt aus:
gui/backend/db/klangkiste.sqlitepruefen.
Test E: Verhalten vor Pairing (keine Steuerung erlaubt)
- Ziel
- Vor Pairing werden Steuerbefehle blockiert.
- Voraussetzungen
- Box UNPAIRED.
- Durchfuehrung – Simulation / Emulation
curl -i -X POST http://127.0.0.1:8000/command -H "Content-Type: application/json" -d '{"command":"play_pause"}'
- Durchfuehrung – Reale Box (Hardware)
- Gleicher Request gegen Box-IP.
- Erwartetes Ergebnis
- HTTP 403 "pairing required".
- Abweichungen / Fehlersuche
- Wenn 200: Pairing-Status und API-Token pruefen.
Test F: Verhalten nach Pairing
- Ziel
- Nach Pairing sind Commands erlaubt (mit Token).
- Voraussetzungen
- Box PAIRED und api_token vorhanden.
- 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"}'
- Durchfuehrung – Reale Box (Hardware)
- Gleiches Vorgehen gegen Box-IP.
- Erwartetes Ergebnis
- HTTP 200, Status aktualisiert.
- Abweichungen / Fehlersuche
- 403: Token pruefen, Pairing-Status pruefen.
Test G: Neustart vor/nach Pairing
- Ziel
- Pairing-Status und Token bleiben ueber Neustart erhalten.
- Voraussetzungen
- Box PAIRED.
- Durchfuehrung – Simulation / Emulation
- Box-Prozess stoppen, neu starten.
- Mit Token Command senden.
- Durchfuehrung – Reale Box (Hardware)
- Power cycle.
- Erwartetes Ergebnis
- Box bleibt PAIRED, Token weiterhin gueltig.
- Abweichungen / Fehlersuche
- Token fehlt:
box/data/secrets.encpruefen.
Test H: Factory Reset -> neue Identitaet
- Ziel
- Factory Reset erzeugt neue Identitaet.
- Voraussetzungen
- Box einmal gestartet.
- Durchfuehrung – Simulation / Emulation
- Box stoppen.
- Dateien loeschen:
rm -f box/data/box.json box/data/state.json box/data/secrets.enc
- Box neu starten.
- Durchfuehrung – Reale Box (Hardware)
- Nicht testbar mit aktuellem Code: kein Reset-Mechanismus.
- Erwartetes Ergebnis
- Neue
box_id.
- Abweichungen / Fehlersuche
box_idbleibt gleich: Dateien nicht geloescht.
Test I: Offline / Backend nicht erreichbar
- Ziel
- Box laeuft weiter ohne Backend.
- Voraussetzungen
- Box laeuft, Backend gestoppt.
- Durchfuehrung – Simulation / Emulation
- Backend stoppen.
- Playback starten (mit Token falls gepairt).
- Durchfuehrung – Reale Box (Hardware)
- Backend vom Netz trennen.
- Erwartetes Ergebnis
- Lokale Playback-Logik laeuft weiter.
- Nicht testbar mit aktuellem Code: Backend markiert OFFLINE nicht.
- Abweichungen / Fehlersuche
- Box stoppt: lokale Logs pruefen.
Test J: Simulation vs. Hardware – Unterschiede
- Ziel
- Unterschiede klar dokumentieren.
- Voraussetzungen
- Box laeuft in Simulation.
- Durchfuehrung – Simulation / Emulation
- WiFi/IP/Spotify/Audio sind Mock.
- Setup UI und API funktionieren lokal.
- Durchfuehrung – Reale Box (Hardware)
- Echte Backends notwendig (nicht implementiert).
- Erwartetes Ergebnis
- Simulation laeuft ohne Hardware.
- Abweichungen / Fehlersuche
- Hardware-Backends fehlen.