Hey, danke für pytest-django! Schätzen Sie all die harte Arbeit, habe es schon einige Male ohne Probleme verwendet.
Wir haben einen kleinen Haken, bei dem wir einige Dinge aktualisiert haben und plötzlich speichert mail.outbox
keine E-Mails während der Tests. Ich habe versucht herauszufinden, wie genau das mailoutbox
Fixture wie hier dokumentiert verwendet wird
Im Moment testen wir in einer Klasse und ich habe einige Konfigurationen ausprobiert, um mailoutbox
Fixture zu bestehen. Dh ich habe die ini aktualisiert:
[pytest]
usefixtures = mailoutbox
Ich bin mir jedoch nicht ganz sicher, wie ich dieses Gerät verwenden soll. Ich habe versucht, das Positionsargument mailoutbox
zu meinen Klassenmethoden hinzuzufügen, kann aber immer noch nicht darauf zugreifen. Ich bin sicher, dass mir etwas Einfaches fehlt.
Würde mich über einen Schubs in die richtige Richtung freuen – und nochmals vielen Dank für dieses Projekt!
Siehe https://github.com/pytest-dev/pytest-django/blob/5da0935731d71aa347c57cd1753f51e3ba9f32d5/docs/helpers.rst#clearing -of-mailoutbox (7aee367).
(Nicht klar, ob ich das Problem richtig verstehe)
Ich glaube, ich habe das gleiche Problem, also habe ich beschlossen, meinen Test auf einen einfachen E-Mail-Versand zu reduzieren und ihn einzeln auszuführen:
def test_reset_password(mailoutbox, db, settings):
text_message = render_to_string('emails/password_reset/password_reset_successful.txt',
context={})
html_message = render_to_string('emails/password_reset/password_reset_successful.html',
context={})
subject = render_to_string('emails/password_reset/password_reset_successful_subject.txt',
context={})
email = EmailMultiAlternatives(
subject=subject,
body=text_message,
from_email="[email protected]",
to=['[email protected]']
)
if html_message:
email.attach_alternative(html_message, "text/html")
email.send()
print(settings.EMAIL_BACKEND)
assert len(mailoutbox) == 1
> assert len(mailoutbox) == 1
E assert 0 == 1
E + where 0 = len([])
accounts/tests/api/test_reset_password.py:200: AssertionError
----------------------------------------------- Captured stdout call ------------------------------------------------
django.core.mail.backends.locmem.EmailBackend
--------------------------------------------- Captured stdout teardown ----------------------------------------------
Jetzt ist der coole Teil, wenn ich die db
Halterung entferne, besteht der Test. Also habe ich versucht, meine Methode django_db_setup
löschen, aber ohne Erfolg ...
Ich stecke im Moment fest.
Ich habe vergessen zu erwähnen, dass es im selben Projekt einige Tests gibt, bei denen das Fixture mailoutbox
zu funktionieren scheint, also habe ich versucht, einen Unterschied zwischen diesen Tests und dem fehlgeschlagenen zu erkennen.
Der einzige Unterschied, den ich gefunden habe, ist die Positionierung des Arguments mailoutbox
in der Testfunktion. Wenn es vor einem Fixture steht, das von dem db
Fixture abhängt, funktioniert es nicht, aber es funktioniert, wenn ich es danach setze, also habe ich wohl einen Workaround gefunden.
Ich kann bestätigen, dass wir dieses Verhalten auch mit pytest-django==3.3.3 sehen
@bogdanpetrea
Danke für die Recherche/Update.
Wird für jemanden hilfreich sein, der dies debuggt/behebt.
Ich bin mir nicht sicher, ob es wirklich damit zusammenhängt, aber ich habe festgestellt, dass es möglicherweise einen AttributeError gibt, weil mail.outbox
nicht gesetzt wurde - aber dies hängt mit der Änderung der Umgebung zusammen, während pytest-django hochfährt.
Ref: https://github.com/pytest-dev/pytest-django/pull/708
Ich habe aktuell das Problem, dass die Mailoutbox nicht leer ist :(
Es ist das neueste Testfunktionsargument.
EDIT: Ich rufe mailoutbox.clear()
vor dem echten Testcode als Work-a-Round auf.
@jedie
Können Sie einen reproduzierbaren Testfall bereitstellen? Ein nicht bestandener Test für pytest-django wäre natürlich das Beste.
Bezogen auf #708? (dh stochern Sie in dem Code herum, den es dort berührt)
Ich habe einen trivialen Testfall erstellt, der das Problem reproduziert (zumindest so, wie ich es erlebe): https://github.com/pytest-dev/pytest-django/compare/master...koniiiik :589- mailoutbox-is-not-django-core-mail-outbox?expand=1
Nach der Art, wie ich mailoutbox
, wäre es auch sehr hilfreich, mailoutbox.clear()
tatsächlich sowohl mailoutbox
als auch mail.outbox
löschen zu können. Wenn mailoutbox is mail.outbox
, dann könnte jemand den Postausgang leeren, bevor Code ausgeführt wird, der dann eine bestimmte Anzahl von E-Mails generieren soll (zB 1
E-Mail).
Ich bin mir nicht sicher, ob dies mit diesem Problem zusammenhängt, aber das mailoutbox
Gerät stimmt nicht mit dem Verhalten von mail.outbox
in meinem Test überein. Es werden keine gesendeten E-Mails gesammelt:
(Pdb) mail.outbox
[<django.core.mail.message.EmailMultiAlternatives object at 0x7f6d864cb198>]
(Pdb) mailoutbox
[]
(Pdb)
Ich bin mir nicht sicher, ob dies mit diesem Problem zusammenhängt, aber das
mailoutbox
Gerät stimmt nicht mit dem Verhalten vonmail.outbox
in meinem Test überein. Es werden keine gesendeten E-Mails gesammelt:(Pdb) mail.outbox [<django.core.mail.message.EmailMultiAlternatives object at 0x7f6d864cb198>] (Pdb) mailoutbox [] (Pdb)
Dasselbe.
mail.outbox
enthält eine Nachricht, während mailoutbox
leer ist.
pytest-django-Version ist 3.9.0.
Ich habe das gleiche Problem.
Wenn ich das Gerät so verwende, schlägt es fehl:
def test_send_foo_mail(mailoutbox, user_client, foo):
So funktioniert es:
def test_send_foo_mail(user_client, foo, mailoutbox):
Ich habe viel Zeit gebraucht, um es zu entdecken. Ich möchte helfen, dies zu debuggen. Ich habe mir die Implementierung angeschaut, aber ich habe keine Ahnung, wie ich das debuggen soll.
Verwandte: https://stackoverflow.com/questions/66846621/mailoutbox-works-only-if-last-fixture
Erlebe das gleiche Verhalten wie der vorherige Kommentator. So zu verwenden funktioniert nicht:
def test_command_and_email(
mailoutbox, argument, time_machine, mocker
):
Aber alles funktioniert wie gewünscht, wenn ich es nur an letzter Stelle setze.
def test_command_and_email(
argument, time_machine, mocker, mailoutbox
):
Argument argument
ist auch ein Fixture, das db
Fixture verwendet, also denke ich, dass dies der Hauptgrund für dieses Verhalten ist.
Ich verwende pytets-django 4.3.0
Hilfreichster Kommentar
Ich glaube, ich habe das gleiche Problem, also habe ich beschlossen, meinen Test auf einen einfachen E-Mail-Versand zu reduzieren und ihn einzeln auszuführen:
Jetzt ist der coole Teil, wenn ich die
db
Halterung entferne, besteht der Test. Also habe ich versucht, meine Methodedjango_db_setup
löschen, aber ohne Erfolg ...Ich stecke im Moment fest.