Testing Email Templates in Rails

Sending email from a Ruby on Rails “application is easy.”:http://guides.rubyonrails.org/action_mailer_basics.html Sending well-formed and aesthetically-pleasing HTML emails that render reliably in all mail clients is rather more difficult.

The code/test/edit cycle can be greatly eased by a number of great tools such as “mail_view”:https://github.com/basecamp/mail_view or “MailCatcher”:http://mailcatcher.me/, but in the end there’s no substitute for actually trying your email templates. There are a lot of “differences in HTML handling across email clients”:http://www.email-standards.org/, so testing your emails is critical.

Here’s an approach to email template testing that I’ve found useful.

Testing Rails Email Templates

1. Get a real SMTP server.

It’s possible to set one up on your development machine if you like, or your company may have one. If you don’t want to go through that setup effort, consider a commercial service like SendGrid. They have a trial level that allows enough deliveries for most development purposes.

2. Configure your development environment to send real emails.

This should be fairly straightforward, and you probably have configuration code for your production environment that you can copy and update. Here’s a piece of my @config/environments/development.rb@:

ActionMailer::Base.smtp_settings = {
  user_name: "my-user",
  password: "my-password",
  address: "smtp.sendgrid.net",
  port: 587
}

config.action_mailer.delivery_method = :whitelist_proxy
config.action_mailer.whitelist_proxy_settings = {
  delivery_method: :smtp,
  domain: %w|atomicobject.com|
}

You’ll note that I am using the “whitelist-mail-proxy”:https://github.com/matthewrudy/whitelist-mail-proxy rubygem. This gem (as its name implies) allows me to whitelist which email domains will receive the real mail. This way I can blast out as many emails as I like and can be confident they’re not going out to real users.

3. Enable Rails’ helpers.

At this point you should be able to send out emails, but we’re not quite done. We need to set the default host name for links and for asset paths in order for Rails’ helpers to be able to work and to generate the correct urls. Try adding this configuration snippet to your environment:

ip_address = UDPSocket.open {|s| s.connect("64.233.187.99", 1); s.addr.last}
config.action_mailer.default_url_options = { :host => "#{ip_address}:3000" }
config.action_mailer.asset_host = "http://#{ip_address}:3000"

This code, from coderrr, asks your operating system to route a UDP packet out to Google and captures the sending IP address (yours), but doesn’t actually send any data. Essentially, this lets us autodetect your address on the local network. Rails’ helpers will use that address in links and asset paths, so when you send mail from your development machine, the recipient will be able to see images hosted off your machine and follow links to that application instance. Since the IP address is detected, any new developer that picks up the project will automatically use paths correct to his machine.

I’m sure there are cases for odd networks, and this trick won’t work if the email client is outside your network, but for most cases this should let you send an email from your development machine, walk over to a machine with Outlook, and see what it looks like.

Other Rails Email Design & Testing Tools

There are a lot of tools out there that can help you design better mails. I’ve successfully used “actionmailer_inline_css”:https://github.com/ndbroadbent/actionmailer_inline_css to automatically copy styles directly into the HTML (needed for GMail). MailChimp has tools to help design mails.

What techniques have you used to make developing email templates less painful?