Zum Inhalt

viur-testing

Sicherer Test-Modus für ViUR-core-Projekte – primär für Playwright-End-to-End-Tests.

Warum viur-testing?

viur-testing schaltet den laufenden viur-core-Prozess auf eine dedizierte benannte Datastore-Datenbank um (Standard: viur-tests) und verweigert jeder Anfrage den Zugriff auf ein Modul, solange der Aufrufer nicht nachweisen kann, dass er bewusst mit der Test-Instanz sprechen wollte. Abgesichert wird das durch mehrere ineinandergreifende Sicherheitsmechanismen.

Inhalt

Das Projekt besteht aus einem PyPI-Package (spltz-viur-testing) und einem npm-Package (@spltz/viur-testing). Das PyPI-Package stellt die Backend-Erweiterung bereit, das npm-Package die Playwright-API sowie einen Stub-Generator.

Python-Package:

  • ViUR-3-core-Patches für Multi-Datastore- und Namespace-Support.
  • Request-Validator zur Token-Prüfung.
  • viur-mirror-Tool zum Kopieren von Daten in eine Namespace-Datastore-Instanz.
  • enter-Endpunkt zum direkten Browsen der Test-Instanz.

npm-Package:

  • Cookie-basierter Token-Transport (Playwright-Fixtures + APIRequestContext).
  • PIN-Bestätigung vor dem Start (Guarded-Modus).
  • Playwright-Patches zum Erzwingen der Sicherheitsmechanismen.
  • init-Tool zum Erzeugen eines Stubs.

Sicherheitsmechanismen

  1. activate() verweigert den Dienst außerhalb von conf.instance.is_dev_server – kein Test-Modus auf einer produktiven Instanz.
  2. DB-Roundtrip – ein Schreib-Lese-Zyklus gegen die Zieldatenbank verifiziert den erfolgreichen Client-Wechsel, bevor der Start fortgesetzt wird.
  3. TestModule und ConfigModule verweigern die Instanziierung außerhalb des Dev-Servers oder ohne vorheriges activate().
  4. Test-API außerhalb von deploy/ – die projektspezifischen Test-Module liegen außerhalb des Deploy-Ordners und werden damit nie in die Produktion ausgeliefert.
  5. Pro-Anfrage-Token-Cookie viur-test-token – jede Anfrage muss den ausgehandelten Token als Cookie mitführen (einmal am Browser-Context gesetzt, oder über /_test/config/enter fürs manuelle Browsen), sonst wird sie abgewiesen. Das Cookie fährt auch bei harter Navigation mit.
  6. Runner-Preflightrequire_test_mode() ruft /_test/config/status auf und verweigert den Teststart, wenn der Server eine andere Datenbank, Projekt-ID oder einen anderen Token-Hash meldet als erwartet.
  7. protect() – installiert in jeder Umgebung den Production-Guard: auf einem Nicht-Dev-Server weist er jede Anfrage mit viur-test-token-Cookie sofort mit 403 ab, sodass ein versehentlich mitgeschicktes Test-Cookie die Live-Instanz nie erreicht.

Endpunkte

  • POST /_test/config/status – stellt den Session-Token in der Test-Datenbank bereit (oder gibt ihn zurück), verifiziert erneut Dev-Server + Datenbank und liefert JSON {test_mode, is_dev_server, database, project_id, token, token_hash, version}. Nur per POST, um Drive-by-GETs aus parallelen Browser-Tabs zu blockieren.
  • GET /_test/config/enter – setzt das viur-test-token-Cookie (SameSite=Strict; HttpOnly; Path=/), damit du die Test-Instanz direkt browsen kannst. Per einfacher Navigation erreichbar; siehe Development-Modus.
  • POST /_test/config/finish – löscht die Token-Entity aus der Test-Datenbank und beendet damit die Session.

Alle drei werden vom ConfigModule innerhalb des TestModule-Containers bereitgestellt. Test-Suiten hängen als zusätzliche Submodule unter demselben /_test/-Schirm.

Minimalbeispiel

Zwei Einzeiler im Host. main.py:

import viur.testing
viur.testing.setup()

from viur.core import setup as core_setup
import modules, render
app = core_setup(modules, render)

modules/__init__.py:

import viur.testing
viur.testing.register_modules(globals())

Runner-seitig:

from viur.testing import require_test_mode, finish

status = require_test_mode("http://localhost:8080")
try:
    # run tests; the viur-test-token cookie is set on the browser context
    ...
finally:
    finish("http://localhost:8080", status.token)

Wie es weitergeht

  • Erste Schritte – schrittweise Verdrahtung von Host + Runner samt GCP-seitiger Vorbereitung (benannte Datastore-Datenbank).
  • Development-Modus – Nutzung während der Entwicklung samt Datenspiegelung.
  • Guarded-Modus – Variante, die im begrenzten Rahmen gegen eine beliebige Datenbank (auch live) laufen kann.
  • Changelog.