3 Stimmen

Monkey hat den Login von django auth gepatcht, jetzt schlagen die Tests fehl

Meine app versucht, die django.contrib.auth.views Login und Logout Ansichten mit einigen grundlegenden Auditing/Protokollierung Fähigkeiten zu wickeln. Ich folge dem Rezept wie beschrieben in der django-axes Projekt, und in der Ausführung auf einem Server und einige andere Tests, es funktioniert wie erwartet, transparent ohne Problem.

Der Code lautet wie folgt:

from django.contrib.auth import views as auth_views
from myapp.watchers import watch_login

class WatcherMiddleware(object):
    def __init__(self):
        auth_views.login = watch_login(auth_views.login)

Und

def watch_login(func):
    def decorated_login(request, *args, **kwargs):
        #do some stuff
        response = func(request, *args, **kwargs)
        #more stuff
        return response
    return decorated_login

Urls:

#Edit: Added project's urls - just using vanilla django's auth login
(r'^accounts/login/$', 'django.contrib.auth.views.login',{"template_name":settings.LOGIN_TEMPLATE }),

In unserem Build-Workflow stoßen wir jedoch auf einige Probleme in der django.contrib.auth.tests.views.

Konkret sind dies die Tests, die in django.contrib.auth fehlschlagen:

ERROR: test_current_site_in_context_after_login (django.contrib.auth.tests.views.LoginTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "C:\Python26\lib\site-packages\django\contrib\auth\tests\views.py", line 192, in test_current_site_in_context_after_login
    response = self.client.get(reverse('django.contrib.auth.views.login'))
  File "C:\Python26\lib\site-packages\django\core\urlresolvers.py", line 351, in reverse
    *args, **kwargs)))
  File "C:\Python26\lib\site-packages\django\core\urlresolvers.py", line 297, in reverse
    "arguments '%s' not found." % (lookup_view_s, args, kwargs))
NoReverseMatch: Reverse for 'myapp.watchers.decorated_login' with arguments '()' and keyword arguments '{}' not found.

======================================================================
ERROR: test_security_check (django.contrib.auth.tests.views.LoginTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "C:\Python26\lib\site-packages\django\contrib\auth\tests\views.py", line 204, in test_security_check
    login_url = reverse('django.contrib.auth.views.login')
  File "C:\Python26\lib\site-packages\django\core\urlresolvers.py", line 351, in reverse
    *args, **kwargs)))
  File "C:\Python26\lib\site-packages\django\core\urlresolvers.py", line 297, in reverse
    "arguments '%s' not found." % (lookup_view_s, args, kwargs))
NoReverseMatch: Reverse for 'myapp.watchers.decorated_login' with arguments '()' and keyword arguments '{}' not found.

Nur diese beiden Tests schlagen fehl, wenn der "Wrapped Login Monkey"-Patch verwendet wird.
Es scheint, als ob der reverse()-Aufruf im django auth-Test sich anders verhält als eine ungepatchte Funktion, die ihr Ding macht.

Der Grund, warum wir diesen Weg für das Wrapping Logging im Gegensatz zu den neuen Authentifizierungssignalen von Django 1.3 gehen, ist, dass die dort vorgesehene Logging-Methode Sie nur informiert, wenn ein falscher Versuch passiert - sie gibt Ihnen keinen Zugriff auf das Request-Objekt, um zusätzliche Informationen über die unzulässige Anfrage zu protokollieren. Parcheando das Authentifizierungsformular wäre in diesem Fall nicht hilfreich gewesen, daher die Notwendigkeit, die Login-Funktion zu verpacken.

Mache ich etwas falsch, wenn ich die Anmeldefunktion umschreibe? Oder ist dies wie zu erwarten, mit Tests fehlschlagen aufgrund von anderen Nebenwirkungen, trotz keine Änderung in der Gesamtfunktionalität?

edit: Ich benutze Python 2.6.4, Django 1.2.5

5voto

Jakub Roztocil Punkte 15326

Könnten Sie es nicht einfach in eine andere Ansicht verpacken?

urls :

url(
    r'^accounts/login/$',
    'accounts.views.login',
    {"template_name":settings.LOGIN_TEMPLATE }
),

accounts.views :

from django.contrib.auth import views as auth_views   

def login(request, *args, **kwars):
    # do some stuff    
    response = auth_views.login(request, *args, **kwars)
    # more stuff
    return response

Zum Beispiel so, django.contrib.auth.tests testen die Ansicht, für die sie geschrieben wurden, und Sie können Ihre eigenen Tests für das "Mehr", das Sie benötigen, schreiben.

3voto

Steve Jalim Punkte 11611

Ich vermute, dass dies das gleiche Problem ist die sich auf die django-registrierung auswirken dass der Testrunner nur die URLs der gerade getesteten Anwendung importiert, d.h, contrib.auth und nicht myapp Es gibt verschiedene Eintrittskarten über Dinge ähnlich wie bei diesem Thema aber ein kurzer Blick darauf deutet darauf hin, dass die Lösung darin besteht, die Dinge zu entkoppeln, was für Ihre Lösung nicht praktikabel ist, wie ich vermute.

Eine andere Möglichkeit wäre, Fabric file oder Makefile zu verwenden, um eine Teilmenge von Tests auszulösen, wobei die beiden, die aufgrund des Monkeypatchs fehlschlagen, vermieden werden, und dann zwei alternative affenfreundliche Tests hinzuzufügen, um sie zu ersetzen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X