Functional testing also can include testing processes that leave your environment, such as external API calls and emails.
As an example, imagine you're functionally testing the registration process for your website. The final step of this process involves sending an email with an activation link. Until this link is visited, the account isn't completely registered. You'd want to test both:
Now you could test the email sending but using an IMAP or POP client to retrieve the sent email from the mailbox, but this means you're also testing your Internet connection, the remote email server and any problems that may arise in delivery (spam detection for instance).
A simpler solution is to use a local service that traps outgoing SMTP connections and dumps the sent email to disk.
A couple of examples are:
smtp-sink - A utility program that comes bundled with Postfix.
# Stop the currently running service
sudo service postfix stop
# Dumps outgoing emails to file as "day.hour.minute.second"
smtp-sink -d "%d.%H.%M.%S" localhost:2500 1000
# Now send mails to your local SMTP server as normal and they will be
# dumped to raw text file for you to open and read
# Run your functional tests
vendor/bin/behat
Don't forget to kill smtp-sink
and restart your postfix service afterwards:
# Restart postfix
sudo service postfix start
FakeSMTP - A Java-based client that traps outgoing mail
# -b = Start without GUI interface
# -o = Which directory to dump your emails to
$ java -jar fakeSMTP.jar -b -o output_directory_name
Alternatively you can use a remote service that provides this service like mailtrap but then your testing is dependent on Internet access.