Laravel is a very popular PHP framework with the built-in ability to send email. This tutorial demonstrates how to use two different email techniques in Laravel to send mail: Mailable and Notification. It then shows how to test that emails are sent correctly using Dusk and MailSlurp fake mail catchers.

Tutorial basics

To illustrate email sending in Laravel let us create a demo app that allows users to sign up for a newsletter using a form and select to be emailed using Mailable or Notification techniques. We will then write Dusk browser tests using Chrome and MailSlurp disposable email addresses to capture the outbound email and verify the results. This is what our project will look like:

When the user visits our site they will be given the choice to sign up to receive an email newsletter. For demonstration purposes we'll make two implementations, one using Mailable and another using Notifications. Full code can be found on the github examples repository.

Notifcations vs Mailable

Laravel provides two primary ways to send notifications to users: Mailables and Notifications. Here's a brief comparison:

AspectMailablesNotifications
PurposeDesigned specifically for email communicationDesigned for quick, simple messages that can be sent via various channels
CustomizationProvides flexibility for complex email layouts and designsOffers customization focused on the message content rather than design
Delivery channelsRestricted to the email channelSupports multiple channels, including mail, database, broadcast, SMS (via Nexmo), and Slack
QueueCan be queued for background sendingCan also be queued for background sending
ComplexityMight be a bit more complex to set up initially, especially with complex designsTypically simpler to set up, particularly if you're using multiple channels

Notifications and Mailables both have their uses. In this post we will show to how use and test both of them.

Setting up a project

Let's assume you have an existing Laravel project with composer. If not create one with:

Then add the MailSlurp library so we can use email addresses. You need an API Key so create a free account to obtain one:

Then configure dusk to enable browser testing:

We can add a basic welcome page with a link to our two different sign up methods (Mailable and Notification):

welcome page

The buttons link to and respectively.

Configure mail settings

Before we can send emails we need to configure PHP mail settings. Laravel sends email using an external SMTP mailserver. We can configure this inside or .

Using .env

If you have created an inbox in MailSlurp then you can use the SMTP access details provided in the MailSlurp dashboard to configure the SMTP credentials inside

The disadvantage of this approach is that the settings are static. For this example we will use instead which allows dynamic configuration.

Using config/mail.php

For this example we want to use create and use a new MailSlurp inbox for sending within the app. We can use the MailSlurp API client inside to configure these settings:

Note that each time you change the config you need to run:

Create a Mailable

To send email using Mailables we can scaffold a class:

Inside the class we define which view we will use:

For the view we used - this means we need to define a blade template view in :

This view will be used as the email body when we send using the Mailable class.

Define a Notification

For the Notification approach we can do something similar using Notification classes

The class looks like so:

Notice here we don't use a view. This is because laravel will style our notifications for us. This is a major difference between Mailables and Notifications.

Create controller routes

We want users to sign up with email addresses for a fake newsletter. Let's use artisan to create controllers and routes for each method:

We will show a form on each page so let's wire up the routes:

Define controllers

So we have defined our routes and mail config. Now let's create a controller for each method.

Mailable controller

For the mailable use we need a form with an email input like this:

Let's define the view:

The important part here is the form and input. We also need a view for when the form is successfully submitted:

This will thank the user after submission. Next we need to wire up the views with our controller and configure the Mailable call:

This configuration allows the user to submit the newsletter form and be emailed using a Mailable. After that we render the success form.

email form

Notification controller

We can also do the same using Notifications. Here we need a similar form with views and controller:

The success page will look like this:

Next we configure the views inside the Notification controller and use the NewsletterNotification class to email the user:

This configures views for submission and success:

email form

Testing the application with Dusk

So now we have created routes, views, and controllers for Mailable and Notification methods. Next we want to define two browser tests that will:

  • Load the welcome page in a browser
  • Click on each link
  • Create a disposable email address
  • Submit the email address for newsletter sign-up
  • Verify that the email is sent and received

What is Dusk?

The most common way to test Laravel applications end-to-end with real browsers is Dusk. Dusk uses Chromedriver to instantiate a headless chrome browser and control it remotely. You can define tests in PHP and assert that our application is functioning correctly.

How does MailSlurp integrate?

The reason for using MailSlurp is that it lets us create throwaway email accounts during tests and use them to sign up and receive emails. We can also use the MailSlurp PHP client to wait for the sent emails and fetch them for verification.

Create Dusk tests

Run integration tests

To run the tests we first need to run the Laravel application in a separate terminal. Then execute .

The test will load the application, create an email address, fill out the form, then wait for the email to arrive:

notification form filled

We then use the method to fetch the render email and view it in our browser:

notification rendered

Notice how the notification is rendered using a Laravel built-in template. The Mailable on the other hand uses only our own blade view:

mailable rendered

Conclusion

Woah! That was a lot of code but we also achieved something remarkable: we sent emails using both Mailable and Notification classes plus we tested it using Dusk integration tests and MailSlurp disposable email addresses. You can do the same and test your application end to end with real email (and SMS).