Skip to content

Commit 4b2f0c5

Browse files
authored
Merge branch 'main' into patch-1
2 parents 78502d3 + 0a8473e commit 4b2f0c5

File tree

3 files changed

+73
-6
lines changed

3 files changed

+73
-6
lines changed

pytest_django/plugin.py

+6-4
Original file line numberDiff line numberDiff line change
@@ -601,7 +601,8 @@ def _dj_autoclear_mailbox() -> None:
601601

602602
from django.core import mail
603603

604-
del mail.outbox[:]
604+
if hasattr(mail, "outbox"):
605+
mail.outbox.clear()
605606

606607

607608
@pytest.fixture()
@@ -610,12 +611,13 @@ def mailoutbox(
610611
_dj_autoclear_mailbox: None,
611612
) -> list[django.core.mail.EmailMessage] | None:
612613
"""A clean email outbox to which Django-generated emails are sent."""
613-
if not django_settings_is_configured():
614-
return None
614+
skip_if_no_django()
615615

616616
from django.core import mail
617617

618-
return mail.outbox # type: ignore[no-any-return]
618+
if hasattr(mail, "outbox"):
619+
return mail.outbox # type: ignore[no-any-return]
620+
return []
619621

620622

621623
@pytest.fixture()

tests/conftest.py

+8-2
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,13 @@ def _marker_apifun(
3030
extra_settings: str = "",
3131
create_manage_py: bool = False,
3232
project_root: str | None = None,
33+
create_settings: bool = True,
3334
):
3435
return {
3536
"extra_settings": extra_settings,
3637
"create_manage_py": create_manage_py,
3738
"project_root": project_root,
39+
"create_settings": create_settings,
3840
}
3941

4042

@@ -135,14 +137,18 @@ def django_pytester(
135137

136138
# Copy the test app to make it available in the new test run
137139
shutil.copytree(str(app_source), str(test_app_path))
138-
tpkg_path.joinpath("the_settings.py").write_text(test_settings)
140+
if options["create_settings"]:
141+
tpkg_path.joinpath("the_settings.py").write_text(test_settings)
139142

140143
# For suprocess tests, pytest's `pythonpath` setting doesn't currently
141144
# work, only the envvar does.
142145
pythonpath = os.pathsep.join(filter(None, [str(REPOSITORY_ROOT), os.getenv("PYTHONPATH", "")]))
143146
monkeypatch.setenv("PYTHONPATH", pythonpath)
144147

145-
monkeypatch.setenv("DJANGO_SETTINGS_MODULE", "tpkg.the_settings")
148+
if options["create_settings"]:
149+
monkeypatch.setenv("DJANGO_SETTINGS_MODULE", "tpkg.the_settings")
150+
else:
151+
monkeypatch.delenv("DJANGO_SETTINGS_MODULE", raising=False)
146152

147153
def create_test_module(test_code: str, filename: str = "test_the_test.py") -> Path:
148154
r = tpkg_path.joinpath(filename)

tests/test_fixtures.py

+59
Original file line numberDiff line numberDiff line change
@@ -864,3 +864,62 @@ def mocked_make_msgid(*args, **kwargs):
864864
result = django_pytester.runpytest_subprocess("--tb=short", "-vv", "-s")
865865
result.stdout.fnmatch_lines(["*test_mailbox_inner*", "django_mail_dnsname_mark", "PASSED*"])
866866
assert result.ret == 0
867+
868+
869+
@pytest.mark.django_project(
870+
create_manage_py=True,
871+
extra_settings="""
872+
EMAIL_BACKEND = "django.core.mail.backends.dummy.EmailBackend"
873+
""",
874+
)
875+
def test_mail_auto_fixture_misconfigured(django_pytester: DjangoPytester) -> None:
876+
"""
877+
django_test_environment fixture can be overridden by user, and that would break mailoutbox fixture.
878+
879+
Normally settings.EMAIL_BACKEND is set to "django.core.mail.backends.locmem.EmailBackend" by django,
880+
along with mail.outbox = []. If this function doesn't run for whatever reason, the
881+
mailoutbox fixture will not work properly.
882+
"""
883+
django_pytester.create_test_module(
884+
"""
885+
import pytest
886+
887+
@pytest.fixture(autouse=True, scope="session")
888+
def django_test_environment(request):
889+
yield
890+
""",
891+
filename="conftest.py",
892+
)
893+
894+
django_pytester.create_test_module(
895+
"""
896+
def test_with_fixture(settings, mailoutbox):
897+
assert mailoutbox == []
898+
assert settings.EMAIL_BACKEND == "django.core.mail.backends.dummy.EmailBackend"
899+
900+
def test_without_fixture():
901+
from django.core import mail
902+
assert not hasattr(mail, "outbox")
903+
"""
904+
)
905+
result = django_pytester.runpytest_subprocess()
906+
result.assert_outcomes(passed=2)
907+
908+
909+
@pytest.mark.django_project(create_settings=False)
910+
def test_no_settings(django_pytester: DjangoPytester) -> None:
911+
django_pytester.create_test_module(
912+
"""
913+
def test_skipped_settings(settings):
914+
assert False
915+
916+
def test_skipped_mailoutbox(mailoutbox):
917+
assert False
918+
919+
def test_mail():
920+
from django.core import mail
921+
assert not hasattr(mail, "outbox")
922+
"""
923+
)
924+
result = django_pytester.runpytest_subprocess()
925+
result.assert_outcomes(passed=1, skipped=2)

0 commit comments

Comments
 (0)