2009-08-24 11 views
3

zu Unittest habe ich eine Anforderung etwas wie folgt aus:Wie Session-Timeout in Django

Sobald der Benutzer signsup (und im Wartezustand sein wird untill er seine E-Mail-Adresse bestätigt), eine Session-Variable gesetzt ist etwas wie "FIRST_TIME_FREE_SESSION_EXPIRY_AGE_KEY" (tut uns leid, wenn der Name verwirrend klingt!), der auf ein Datetime-Objekt gesetzt wird, das der aktuellen Zeit 8 Stunden hinzufügt.

Wie sich dies auf den Benutzer auswirkt, erhält der Benutzer 8 Stunden Zeit, um alle Funktionen unserer Website zu nutzen, ohne seine registrierte E-Mail-Adresse zu bestätigen. Nach 8 Stunden zeigt jede Ansicht/Seite ein großes Banner, das den Benutzer zur Bestätigung auffordert. (All diese Funktionalität wird durch die Verwendung eines einzelnen Dekorators "use_confirmed_user" für jede Ansicht erreicht).

Ich möchte die gleiche Funktionalität mit Django Unittest Addon (TestCase-Klasse) testen. Wie mache ich es?

Update: Muss ich den Wert der Sitzungsvariablen manuell aktualisieren (8 Stunden bis ein paar Sekunden geändert), um es fertig zu machen? Oder gibt es einen besseren Weg?

Update: Das mag verrückt klingen, aber ich möchte eine Anfrage aus der Zukunft simulieren.

+0

[freezegun] (https://pypi.python.org/pypi/freezegun/) lassen Sie uns Zeit nach Belieben in den Tests manipulieren. Der resultierende Test wird auch schön explizit sein. –

Antwort

0

Ich kann mir ein paar Möglichkeiten vorstellen. Überschreiben Sie während des Testlaufs die Variable FIRST_TIME_FREE_SESSION_EXPIRY_AGE_KEY und setzen Sie sie auf ein kleineres Zeitlimit. Sie können dann warten, bis das Zeitlimit überschritten ist, und überprüfen, ob das Feature wie erwartet funktioniert.

Alternativ Ihre eigenen datetime Funktionen ersetzen (basiert auf datetime Ihre Funktion vorausgesetzt) ​​

Sie diese durch zwingende setup_ und teardown_test_environment Methoden erreichen kann.

3

Wenn Komponententests schwierig sind, weil der Produktcode von externen Ressourcen abhängt, die nicht kooperieren, können Sie diese Ressourcen abstrahieren und durch Dummies ersetzen, die das tun, was Sie wollen.

In diesem Fall ist die externe Ressource die Zeit. Anstatt datetime.now() zu verwenden, refaktorieren Sie den Code, um eine externe Zeitfunktion zu akzeptieren. Es kann standardmäßig auf datetime.now festgelegt werden. Dann können Sie in Ihren Komponententests die Zeit ändern, während der Test fortschreitet.

Das ist besser, als das Session-Timeout auf ein paar Sekunden zu ändern, denn selbst dann müssen Sie für einige Sekunden im Test schlafen, um den gewünschten Effekt zu erhalten. Komponententests sollten so schnell wie möglich ausgeführt werden, sodass sie häufiger ausgeführt werden.

0

Meine settings.py unterscheidet sich leicht, je nachdem, ob django in einer Produktionsumgebung oder in einer Entwicklungsumgebung ausgeführt wird. Ich habe 2 Einstellungen Module: settings.py und settings_dev.py. Die Entwicklung Version sieht wie folgt aus:

from settings import * 

DEBUG = True 

INSTALLED_APPS = tuple(list(INSTALLED_APPS) + [ 
      'dev_app', 
      ]) 

Jetzt können Sie Ihr Problem auf verschiedene Arten lösen:

  1. die Variable mit unterschiedlichen Werten für beide Einstellungen Module hinzufügen;
  2. Wenn Sie die Variable festlegen, wählen Sie zwischen zwei Werten entsprechend dem Wert der DEBUG-Einstellung. Sie können DEBUG auch verwenden, um den Komponententest auf dem Produktionsserver wegzulassen, da der Test dort sowieso zu lange dauern wird.

Sie können die aktiven Einstellungen Modul wie folgt verwenden:

from django.conf.project_template import settings 

if settings.DEBUG: 
    ...