or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

client-testing.mddatabase-testing.mddjango-assertions.mddjango-utilities.mdemail-testing.mdindex.mdlive-server-testing.mdpytest-marks.mdquery-testing.mdsettings-management.mdtransaction-callbacks.mduser-management.md

email-testing.mddocs/

0

# Email Testing

1

2

Email testing fixtures for capturing and testing Django email functionality. These fixtures provide access to Django's email outbox and DNS configuration for comprehensive email testing.

3

4

## Capabilities

5

6

### Email Outbox

7

8

Fixture providing access to Django's email outbox for testing sent emails.

9

10

```python { .api }

11

def mailoutbox() -> List[django.core.mail.EmailMessage]:

12

"""

13

Access Django's email outbox for testing sent emails.

14

15

Returns a list of EmailMessage objects that have been sent during

16

the test. The outbox is automatically cleared between tests.

17

Requires Django's locmem email backend or test email backend.

18

19

Returns:

20

List[EmailMessage]: List of email messages sent during test

21

"""

22

```

23

24

Usage example:

25

```python

26

from django.core import mail

27

28

def test_email_sending(mailoutbox):

29

from django.core.mail import send_mail

30

31

# Send an email

32

send_mail(

33

subject="Test Subject",

34

message="Test message body",

35

from_email="from@example.com",

36

recipient_list=["to@example.com"],

37

)

38

39

# Check that email was sent

40

assert len(mailoutbox) == 1

41

email = mailoutbox[0]

42

assert email.subject == "Test Subject"

43

assert email.body == "Test message body"

44

assert email.from_email == "from@example.com"

45

assert email.to == ["to@example.com"]

46

47

def test_multiple_emails(mailoutbox):

48

from django.core.mail import send_mail

49

50

# Send multiple emails

51

send_mail("Subject 1", "Body 1", "from@example.com", ["to1@example.com"])

52

send_mail("Subject 2", "Body 2", "from@example.com", ["to2@example.com"])

53

54

# Check all emails

55

assert len(mailoutbox) == 2

56

assert mailoutbox[0].subject == "Subject 1"

57

assert mailoutbox[1].subject == "Subject 2"

58

59

def test_email_with_attachments(mailoutbox):

60

from django.core.mail import EmailMessage

61

62

email = EmailMessage(

63

subject="Test with attachment",

64

body="Message with attachment",

65

from_email="from@example.com",

66

to=["to@example.com"],

67

)

68

email.attach("test.txt", "File content", "text/plain")

69

email.send()

70

71

assert len(mailoutbox) == 1

72

sent_email = mailoutbox[0]

73

assert len(sent_email.attachments) == 1

74

assert sent_email.attachments[0] == ("test.txt", "File content", "text/plain")

75

```

76

77

### Email DNS Patching

78

79

Fixture that patches DNS name used in email message headers.

80

81

```python { .api }

82

def django_mail_patch_dns() -> None:

83

"""

84

Patch DNS name used in Django email message headers.

85

86

Patches the DNS_NAME used by Django's email system to use

87

a test-friendly DNS name instead of the system's actual DNS name.

88

Automatically uses the value from django_mail_dnsname fixture.

89

"""

90

```

91

92

### Email DNS Name

93

94

Fixture providing the DNS name used for email testing.

95

96

```python { .api }

97

def django_mail_dnsname() -> str:

98

"""

99

Provide DNS name for email testing.

100

101

Returns the DNS name used in email message headers during testing.

102

Default value is "fake-tests.example.com" but can be overridden

103

by parametrizing this fixture.

104

105

Returns:

106

str: DNS name for email testing (default: "fake-tests.example.com")

107

"""

108

```

109

110

Usage example:

111

```python

112

def test_email_dns_name(mailoutbox, django_mail_dnsname):

113

from django.core.mail import send_mail

114

115

send_mail(

116

subject="Test DNS",

117

message="Test message",

118

from_email="from@example.com",

119

recipient_list=["to@example.com"],

120

)

121

122

# Check that custom DNS name is used

123

assert django_mail_dnsname == "fake-tests.example.com"

124

# Email will use this DNS name in headers

125

126

# Override DNS name for specific test

127

@pytest.fixture

128

def django_mail_dnsname():

129

return "custom-test.example.com"

130

131

def test_custom_dns_name(mailoutbox, django_mail_dnsname):

132

# This test will use "custom-test.example.com" as DNS name

133

pass

134

```

135

136

## Email Configuration

137

138

For email testing to work properly, configure Django settings:

139

140

```python

141

# In Django settings for testing

142

EMAIL_BACKEND = 'django.core.mail.backends.locmem.EmailBackend'

143

144

# Or in test

145

def test_with_locmem_backend(settings, mailoutbox):

146

settings.EMAIL_BACKEND = 'django.core.mail.backends.locmem.EmailBackend'

147

# Now mailoutbox will capture emails

148

```

149

150

## Email Testing Types

151

152

```python { .api }

153

from django.core.mail import EmailMessage, EmailMultiAlternatives

154

from typing import List, Tuple, Optional, Any

155

156

# Email message types

157

EmailMessageType = EmailMessage

158

EmailList = List[EmailMessage]

159

160

# Email content types

161

EmailSubject = str

162

EmailBody = str

163

EmailAddress = str

164

EmailAddressList = List[str]

165

166

# Attachment types

167

AttachmentTuple = Tuple[str, str, str] # (filename, content, mimetype)

168

AttachmentList = List[AttachmentTuple]

169

170

# DNS configuration

171

DnsName = str

172

173

# Email message structure

174

class EmailMessage:

175

subject: str

176

body: str

177

from_email: str

178

to: List[str]

179

cc: List[str]

180

bcc: List[str]

181

reply_to: List[str]

182

attachments: List[AttachmentTuple]

183

extra_headers: dict[str, str]

184

185

def send(self, fail_silently: bool = False) -> bool: ...

186

def attach(self, filename: str, content: str, mimetype: str) -> None: ...

187

def attach_file(self, path: str, mimetype: Optional[str] = None) -> None: ...

188

189

class EmailMultiAlternatives(EmailMessage):

190

alternatives: List[Tuple[str, str]] # (content, mimetype)

191

192

def attach_alternative(self, content: str, mimetype: str) -> None: ...

193

194

# Mail outbox access

195

from django.core import mail

196

MailOutbox = mail.outbox

197

```