mirror of
https://github.com/pacnpal/django-anymail.git
synced 2025-12-20 03:41:05 -05:00
Clean up and document Anymail's test EmailBackend
* Change Anymail's test EmailBackend to collect sent messages in django.core.mail.outbox, same as Django's own locmem EmailBackend. (So Django's test runner will automatically clear accumulated mail between test cases.) * Rename EmailMessage `test_response` attr to `anymail_test_response` to avoid conflicts, and record merged ESP send params in new `anymail_send_params` attr. * Add docs Closes #36.
This commit is contained in:
@@ -218,11 +218,13 @@ ESP send status
|
||||
if you try to access it.
|
||||
|
||||
This might cause problems in your test cases, because Django
|
||||
`substitutes its own locmem email backend`_ during testing (so anymail_status
|
||||
won't be set even after sending). Your code should either guard against
|
||||
a missing anymail_status attribute, or use :class:`AnymailMessage`
|
||||
(or the :class:`AnymailMessageMixin`) which initializes its anymail_status
|
||||
attribute to a default AnymailStatus object.
|
||||
:ref:`substitutes its own locmem EmailBackend <django:topics-testing-email>`
|
||||
during testing (so anymail_status never gets attached to the EmailMessage).
|
||||
If you run into this, you can: change your code to guard against
|
||||
a missing anymail_status attribute; switch from using EmailMessage to
|
||||
:class:`AnymailMessage` (or the :class:`AnymailMessageMixin`) to ensure the
|
||||
anymail_status attribute is always there; or substitute
|
||||
:ref:`Anymail's test backend <test-backend>` in any affected test cases.
|
||||
|
||||
After sending through an Anymail backend,
|
||||
:attr:`~AnymailMessage.anymail_status` will be an object with these attributes:
|
||||
@@ -321,10 +323,6 @@ ESP send status
|
||||
message.anymail_status.esp_response.json()
|
||||
|
||||
|
||||
.. _substitutes its own locmem email backend:
|
||||
https://docs.djangoproject.com/en/stable/topics/testing/tools/#email-services
|
||||
|
||||
|
||||
.. _inline-images:
|
||||
|
||||
Inline images
|
||||
|
||||
@@ -10,6 +10,7 @@ done with Anymail:
|
||||
multiple_backends
|
||||
django_templates
|
||||
securing_webhooks
|
||||
test_backend
|
||||
|
||||
.. TODO:
|
||||
.. Working with django-mailer(2)
|
||||
|
||||
52
docs/tips/test_backend.rst
Normal file
52
docs/tips/test_backend.rst
Normal file
@@ -0,0 +1,52 @@
|
||||
.. _test-backend:
|
||||
|
||||
Testing your app
|
||||
================
|
||||
|
||||
Django's own test runner makes sure your
|
||||
:ref:`test cases don't send email <django:topics-testing-email>`,
|
||||
by loading a dummy EmailBackend that accumulates messages
|
||||
in memory rather than sending them. That works just fine with Anymail.
|
||||
|
||||
Anymail also includes its own "test" EmailBackend. This is intended primarily for
|
||||
Anymail's own internal tests, but you may find it useful for some of your test cases, too:
|
||||
|
||||
* Like Django's locmem EmailBackend, Anymail's test EmailBackend collects sent messages
|
||||
in :data:`django.core.mail.outbox`.
|
||||
Django clears the outbox automatically between test cases.
|
||||
See :ref:`email testing tools <django:topics-testing-email>` in the Django docs for more information.
|
||||
|
||||
* Unlike the locmem backend, Anymail's test backend processes the messages as though they
|
||||
would be sent by a generic ESP. This means every sent EmailMessage will end up with an
|
||||
:attr:`~anymail.message.AnymailMessage.anymail_status` attribute after sending,
|
||||
and some common problems like malformed addresses may be detected.
|
||||
(But no ESP-specific checks are run.)
|
||||
|
||||
* Anymail's test backend also adds an :attr:`anymail_send_params` attribute to each EmailMessage
|
||||
as it sends it. This is a dict of the actual params that would be used to send the message,
|
||||
including both Anymail-specific attributes from the EmailMessage and options that would
|
||||
come from Anymail settings defaults.
|
||||
|
||||
Here's an example:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from django.core import mail
|
||||
from django.test import TestCase
|
||||
from django.test.utils import override_settings
|
||||
|
||||
@override_settings(EMAIL_BACKEND='anymail.backends.test.EmailBackend')
|
||||
class SignupTestCase(TestCase):
|
||||
# Assume our app has a signup view that accepts an email address...
|
||||
def test_sends_confirmation_email(self):
|
||||
self.client.post("/account/signup/", {"email": "user@example.com"})
|
||||
|
||||
# Test that one message was sent:
|
||||
self.assertEqual(len(mail.outbox), 1)
|
||||
|
||||
# Verify attributes of the EmailMessage that was sent:
|
||||
self.assertEqual(mail.outbox[0].to, ["user@example.com"])
|
||||
self.assertEqual(mail.outbox[0].tags, ["confirmation"]) # an Anymail custom attr
|
||||
|
||||
# Or verify the Anymail params, including any merged settings defaults:
|
||||
self.assertTrue(mail.outbox[0].anymail_send_params["track_clicks"])
|
||||
Reference in New Issue
Block a user