¡Hola, gracias por pytest-django! Aprecio todo el trabajo duro, lo he usado varias veces sin problemas.
Nos encontramos con un pequeño inconveniente en el que actualizamos algunas cosas y, de repente, mail.outbox
no retiene los correos electrónicos durante las pruebas. Intenté averiguar cómo usar exactamente el accesorio mailoutbox
como se documenta aquí, pero tengo problemas para usarlo.
Ahora mismo estamos probando en una clase y he probado bastantes configuraciones para pasar mailoutbox
fixture. Es decir, actualicé el ini:
[pytest]
usefixtures = mailoutbox
Sin embargo, no estoy exactamente seguro de cómo usar ese dispositivo, intenté agregar el argumento posicional mailoutbox
a mis métodos de clase, pero todavía no puedo acceder a él ... Estoy seguro de que me estoy perdiendo algo simple.
Agradecería un empujón en la dirección correcta y, de nuevo, ¡muchas gracias por este proyecto!
Consulte https://github.com/pytest-dev/pytest-django/blob/5da0935731d71aa347c57cd1753f51e3ba9f32d5/docs/helpers.rst#clearing -of-mailoutbox (7aee367).
(Sin embargo, no está claro si entiendo el problema correctamente)
Creo que estoy teniendo el mismo problema, así que decidí reducir mi prueba a un envío de correo electrónico básico y ejecutarla individualmente:
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 ----------------------------------------------
Ahora lo bueno es que si elimino el accesorio db
, la prueba pasa. Así que intenté eliminar mi método django_db_setup
, pero fue en vano ...
Estoy atascado en este momento.
Olvidé mencionar que hay algunas pruebas, en el mismo proyecto, donde el accesorio mailoutbox
parece funcionar, así que traté de detectar cualquier diferencia entre esas pruebas y la que falla.
La única diferencia que encontré es el posicionamiento del argumento mailoutbox
en la función de prueba. Si está antes de cualquier accesorio que dependa del accesorio db
, no funciona, pero funciona si lo coloco después, así que supongo que encontré una solución.
Puedo confirmar que también estamos viendo este comportamiento con pytest-django == 3.3.3
@bogdanpetrea
Gracias por la investigación / actualización.
Será útil para alguien que esté depurando / arreglando esto.
No estoy seguro de si está realmente relacionado, pero descubrí que podría haber un AttributeError debido a que mail.outbox
no se configuró en primer lugar, pero esto está relacionado con cambiar el entorno mientras pytest-django gira.
Ref: https://github.com/pytest-dev/pytest-django/pull/708
Actualmente tengo el problema, ese buzón de correo no está vacío :(
Es el último argumento de la función de prueba.
EDITAR: llamo mailoutbox.clear()
antes del código de prueba real como trabajo de una ronda.
@jedie
¿Puede proporcionar un caso de prueba reproducible? Una prueba fallida para pytest-django sería la mejor, por supuesto.
¿Relacionado con # 708? (es decir, hurgue en el código que toca allí)
He creado un caso de prueba trivial que reproduce el problema (al menos de la forma en que lo estoy experimentando): https://github.com/pytest-dev/pytest-django/compare/master...koniiiik : 589- mailoutbox-is-not-django-core-mail-outbox? expand = 1
Por cómo he usado mailoutbox
, también sería muy útil poder tener mailoutbox.clear()
realidad borrados tanto mailoutbox
como mail.outbox
. Si mailoutbox is mail.outbox
, entonces alguien podría borrar la bandeja de salida antes de ejecutar el código que se supone que genera un número específico de correos electrónicos (es decir, digamos 1
correo electrónico).
No estoy seguro si esto está relacionado con este problema, pero el accesorio mailoutbox
no coincide con el comportamiento de mail.outbox
en mi prueba. No recopila los correos electrónicos enviados:
(Pdb) mail.outbox
[<django.core.mail.message.EmailMultiAlternatives object at 0x7f6d864cb198>]
(Pdb) mailoutbox
[]
(Pdb)
No estoy seguro si esto está relacionado con este problema, pero el accesorio
mailoutbox
no coincide con el comportamiento demail.outbox
en mi prueba. No recopila los correos electrónicos enviados:(Pdb) mail.outbox [<django.core.mail.message.EmailMultiAlternatives object at 0x7f6d864cb198>] (Pdb) mailoutbox [] (Pdb)
Mismo.
mail.outbox
contiene un mensaje mientras que mailoutbox
está vacío.
La versión de pytest-django es 3.9.0.
Tengo el mismo problema.
Si uso el accesorio como este, falla:
def test_send_foo_mail(mailoutbox, user_client, foo):
Así funciona:
def test_send_foo_mail(user_client, foo, mailoutbox):
Me tomó mucho tiempo descubrirlo. Me gustaría ayudar a depurar esto. Miré la implementación, pero no tengo ni idea de cómo depurar esto.
Relacionado: https://stackoverflow.com/questions/66846621/mailoutbox-works-only-if-last-fixture
Experimentar el mismo comportamiento que el comentarista anterior. Usarlo así no funciona:
def test_command_and_email(
mailoutbox, argument, time_machine, mocker
):
Pero todo funciona como se ejecutó si lo pongo en el último lugar.
def test_command_and_email(
argument, time_machine, mocker, mailoutbox
):
El argumento argument
también es un accesorio que usa db
accesorio, así que supongo que esa es la razón principal de este comportamiento.
Estoy usando pytets-django 4.3.0
Comentario más útil
Creo que estoy teniendo el mismo problema, así que decidí reducir mi prueba a un envío de correo electrónico básico y ejecutarla individualmente:
Ahora lo bueno es que si elimino el accesorio
db
, la prueba pasa. Así que intenté eliminar mi métododjango_db_setup
, pero fue en vano ...Estoy atascado en este momento.