# Test emails with Cucumber and Ruby

Cucumber is an extremely popular behaviour driven test framework used by developers around the world. It started as a Ruby project but now supports many languages and use cases.

Test email cucumber

MailSlurp is a free Email API that let's you generate random email addresses on demand for use in tests. You can use them to send and receive real emails in a range of languages (including Ruby, Java, Javascript and more).

This post will demonstrate how to use MailSlurp with Cucumber to test any email related process with real emails.

# The Gherkin Syntax

Cucumber tests are built around human readable scenarios written in Gherkin syntax. These tests look a bit like this:

Scenario: A user visits my website
  Given the user is new
  When the user clicks login
  Then the sign up screen is shown

Note: Gherkins are very popular in Germany, where MailSlurp is based 😄.

# Testing Email with Cucumber

To test email using real emails all we need to do is wire MailSlurp into our Cucumber tests. Let's write an example in Ruby to demonstrate.

# Setup

To get started make sure you have Ruby installed. Create a new project and add the following to a Gemspec file.

source "https://rubygems.org"
group :test do
  gem 'cucumber', '~> 3.1.0'
  gem 'rspec', '~> 3.7.0'
  gem 'mailslurp_client', '~> 5.0.0', '>= 5.0.0'
end

Now run bundle install --path ./vendor/bundle and we are ready to write some tests.

# Writing tests

Cucumber tests live in a features folder. Let's create that and add a new test feature and some step definitions.

features
├── can_i_send_and_receive_email.feature
└── step_definitions
    └── stepdefs.rb

Inside the .feature file let's write a Gherkin scenario that tests the sending and receiving of an email in a Cucumber test.

Feature: Can I Send and Receive Email?
  Send and receive real emails in Cucumber using MailSlurp
  Scenario: Generate test email accounts
    Given a new email address
    When I ask for email address
    Then it should contain "@mailslurp.com"
  Scenario: Send a test email and receive it in code
    Given a new email address
    When I create new email
    When I set subject to "Hello"
    When I set body to "World"
    When I send email to created address
    Then I can receive email
    Then I can see "Hello" in subject
    Then I can see "World" in body

If we run bundle exec cucumber Cucumber will tell us (rightly) that we are missing step definitions for each When, Then clause. We will define those next.

# Defining steps

The magic of Cucumber tests happens in your steps files. Theses files map Gherkin scenarios to real logic in your chosen programming language. Here we are using Ruby as it is popular but MailSlurp supports all other Cucumber supported languages.

# Configuring MailSlurp

Inside stepdefs.rb let's add the following:

require 'mailslurp_client'
# Setup mailslurp
MailSlurpClient.configure do |config|
  config.api_key['x-api-key'] = ENV['API_KEY']
end
api_instance = MailSlurpClient::CommonOperationsApi.new
extra_instance = MailSlurpClient::ExtraOperationsApi.new

This instantiates a MailSlurp client for our email logic with an API KEY environment variable.

⚠️ Note: MailSlurp requires an api key. You can get one free in the dashboard.

# Writing email logic

Now that MailSlurp is configured we can use it in our step definitions to create new email addresses, send real emails, and wait for emails to be received. We can then make assertions on the content of the received email.

MailSlurp supports many other features like custom domains, attachments, email pattern matching and more. See the about page for more information.

Given("a new email address") do
  # generate a new test email account on demand
  @inbox = api_instance.create_new_email_address
end
When("I ask for email address") do
  # inbox has a real email address
  @email_address = @inbox.email_address
end
Then("it should contain {string}") do |string|
    expect(@email_address).to include(string)
end
When("I create new email") do
    @email_options = MailSlurpClient::SendEmailOptions.new
end
When("I set subject to {string}") do |string|
    @email_options.subject = string
end
When("I set body to {string}") do |string|
    @email_options.body = string
end
When("I send email to created address") do
  # send an email to the inbox we created (just as an example)
  @email_options.to = [@inbox.email_address]
  extra_instance.send_email(@inbox.id, @email_options)
end
Then("I can receive email") do
    # wait for emails to arrive in the given inbox
    opts = {
        'inbox_id': @inbox.id,
        'timeout': 10000
    }
    @received_email = api_instance.wait_for_latest_email(opts)
end
# make assertions about the email
Then("I can see {string} in subject") do |string|
  expect(@received_email.subject).to include(string)
end
Then("I can see {string} in body") do |string|
  expect(@received_email.body).to include(string)
end

# Running the tests

Now if we run API_KEY=your-api-key bundle exec cucumber we will see the following output!

Feature: Can I Send and Receive Email?
  Send and receive real emails in Cucumber using MailSlurp
  Scenario: Generate test email accounts
    Given a new email address
    When I ask for email address
    Then it should contain "@mailslurp.com"
  Scenario: Send a test email and receive it in code
    Given a new email address
    When I create new email
    When I set subject to "Hello"
    When I set body to "World"
    When I send email to created address
    Then I can receive email
    Then I can see "Hello" in subject
    Then I can see "World" in body
2 scenarios (2 passed)
11 steps (11 passed)
0m2.663s

# Next steps

Imagine the possibilities. Unlimited real email addresses at your disposal in Cucumber test. MailSlurp is free for personal use and available now.

# Source code

You can find the full source for this post plus more on our Github page.

If you have ideas for future posts please let us know on Twitter.