28 мая 2014 в 22:47

Отладка электронной почты при помощи MailCatcher перевод tutorial

imageВы используете в своем приложении электронную почту, не так ли? Это, в общем-то, риторический вопрос, конечно используете. Ей уже больше 30 лет, а это по прежнему самое популярное средство коммуникации на планете. Вот некоторые статистические данные от Pingdom:
  • 2,2 млрд. — Количество пользователей электронной почты по всему миру
  • 144 млрд.- Объем отправляемых электронных писем ежедневно во всем мире
  • 4,3 млрд.- Количество почтовых клиентов во всем мире

Потрясающе!

Зачем нужна эта статья?


По одной простой причине, с которой мы все так или иначе сталкиваемся. Необходимо тестировать функционал как можно ближе к реальному применению, и любая ошибка может привести к тому, что наши клиенты получат тестовые письма, и это будет печально.

Я уверен, вы знаете о чем я говорю. Думая, что перевели приложение в режим отладки, вы запускаете тест, который отправляет письма из вашего приложения. Вы думаете что никто кроме вас не увидит эти письма.

Тесты проходят, вы хвалите себя и продолжаете работу. Но спустя некоторые время вы получаете звонок от своего заказчика. Он жалуется, что его клиенты получили странные. Он расстроен и хочет получит ответ.

Было такое? Не хочется, чтобы повторилось? Есть решение — MailCatcher. Если вы не слышали о нем то вкратце:
… Супер-простой SMTP-сервер, который перехватывает любое отправленное сообщение и выводит его в веб-интерфейсе. Запустите mailcatcher, в настройках вашего приложения укажите smtp://127.0.0.1:1025 вместо SMTP-сервера по умолчанию, и затем просматривайте почту, которая была отправлена по адресу 127.0.0.1:1080


Неплохо звучит, верно? Независимо от того, устали ли вы, перегружены работой, есть ли новенький в команде или еще какая беда — MailCatcher гарантирует, что электронная почта останется в пределах вашей сети, или даже вашей виртуальной машины.

Сейчас я хочу показать вам, как настроить, запустить и использовать MailCatcher.

Подготовленная виртуальная машина


Чтобы сэкономит немного вашего времени, я создал Vagrant box с уже настроенным MailCatcher. Убедитесь, что Vagrant и VirtualBox у вас установлены и клонируйте себе репозитарий, используя следующую команду:
git clone git@github.com:sitepoint-examples/mailcatcher-article.git

Затем, перейдя в полученный каталог исполните команду:
vagrant up

Будет запущен процесс инициализации виртуальной машины. Настройки её довольно минималистичны, в комплект входит MailCatcher, Sendmail и Nginx.
Прим. пер.: если вы используете puphpet (что это) для сборки виртуальных машин, то замечу, что установка MailCatcher доступна в нем как опция, ну и куча других плюшек, рекомендую.


Установка MailCatcher вручную


Если вы желаете установить MailCatcher сами, то вот последовательность команд:
sudo apt-get install -y vim curl python-software-properties lynx nginx
sudo apt-get install -y php5-fpm php5-memcache memcached php-apc
sudo apt-get install -y build-essential libsqlite3-dev ruby1.9.3
sudo gem install mailcatcher
sudo mailcatcher --http-ip 0.0.0.0

Возможно 3-я команда вам не понадобится, но я использую довольно минималистичный образ Ubuntu Precise 64, и нужных пакетов не оказалось. Если вы используете другой дистрибутив, пакеты и их версии могут отличаться от приведенных выше.

Примечание. При стандартном запуске MailCatcher будет слушать только ip 127.0.0.1 и порт 1025, в этом случае мы не увидели бы его извне. Я изменил конфигурацию так, чтобы она прослушивала все ip-адреса и добавил public ip 192.168.56.111.

Веб-интерфейс MailCatcher


Теперь, перейдя по 192.168.56.111:1080 вы можете наблюдать веб-интерфейс, выглядеть это будет вот так:
Веб-интерфейс MailCatcher
Интерфейс довольно лаконичный, в верхней его части находится список электронных писем, полученным MailCatcher. Когда в списке есть письма, то в нижней части будет выведена информация о них, что мы увидем чуть позже.

Пример использования


Для этой статьи я создал простой php-скрипт, index.php, он присутствует в репозитарии, у нас он доступен по адресу 192.168.56.111. Для отправки писем используется библиотека SwiftMailer. Взгляните на код ниже:
<?php require_once('mail-loader.php'); ?>
<html>
<head>
    <title>Simple MailCatcher PHP Example</title>
</head>
<body>
    <h1>Simple MailCatcher PHP Example</h1>
    <p>This application sends a number of emails which will be caught by MailCatcher. To check them, view them in <a href="http://192.168.56.111:1080/" target="_blank">the local MailCatcher installation</a></p>
</body>
</html>

Он, в свою очередь подключает mail-loader.php:
<?php
require('vendor/autoload.php');
$email = 'matthew@example.com';
$subject = 'testing';
$message = 'test message';

$transport = Swift_SmtpTransport::newInstance(
    "localhost", 1025
);

$message = Swift_Message::newInstance();
$message->setTo(array(
    "matthew@maltblue.com" => "Matthew Setter",
));
$message->setSubject(
    "This email is sent using Swift Mailer"
);
$message->setBody("You're our best client ever.");
$message->setFrom("matthew@localhost", "Your bank");

$mailer = Swift_Mailer::newInstance($transport);
$mailer->send($message, $failedRecipients);
print_r($failedRecipients);


Если вы не знакомы с SwiftMailer статья Аурелио на SitePoint будет хорошим стартом в её изучении. Кстати, это его код я использовал для этого примера. Спасибо, Аурелио.

Из приведенного скрипта для нас, в принципе, важна только одна строчка кода:
$transport = Swift_SmtpTransport::newInstance(
    "localhost", 1025
);

Здесь создается соединение с smtp-сервером MailCatcher, ничего сложного. Давайте перезагрузим страницу 3 раза, чтобы отправилось 3 письма. Вот они, на изображении ниже:
image
Выбрав первую запись мы видим информацию о письме а также его тело. Если мы перейдем на вкладку Source, как на изображении ниже, то увидем заголовки письма:
image
3-я вкладка позволит нам использовать Fractal для анализа содержимого письма. Её я пропущу, т.к. это немного выходит за рамки сегодняшней статьи.

Все готово для работы


Теперь, установив MailCatcher мы можем посылать электронный письма, установив получателей, тему, добавляя вложения и т.д. Можем писать тесты, проверяющие весь процесс работы приложения, зная, что реальные пользователи не получат письма, для них не предназначенные. Это не может не радовать.

Заключение


Мой пример довольно тривиален, и я уверен, что ваша кодовая база более сложна и изощренна, но независимо от этого практически без каких бы то ни было изменений в вашем коде вы можете пользоваться преимуществами работы с MailCatcher и быть спокойны.

Может быть вы уже используете MailCatcher? Что вы можете сказать об итогах его интеграции, были ли какие-то вопросы, которые застали вас врасплох. Буду рад, если вы поделитесь своими мыслями.

Этот и другие переводы с сайта Sitepoint, а также прочие статьи о web-разработке.
Автор оригинала: Matthew Setter
Антон Кармазин @kriptomen
карма
39,0
рейтинг 0,0
Пользователь

Комментарии (17)

  • +4
    3-я вкладка позволит нам использовать Fractal для анализа содержимого письма. Её я пропущу, т.к. это немного выходит за рамки сегодняшней статьи.

    Вкладка вроде уже не работает, так как сервис не рабочий.

    Для того, что бы ничего не ставить можно просто воспользоватся mailtrap.io. В нем есть еще анализ письма на спам, блеклист списки и таже проверка css (если в письме есть HTML).

    Также не так давно на хабре была статья про debugmail.io — habrahabr.ru/post/217201/ В нем нет плюшек с анализом письма, но «акцент на совместную работу» есть.
    • 0
      Спасибо за ссылки, хорошие альтернативы.
  • +4
    Для пользователей Windows просто оставлю это здесь.
    Мне очень удобно.
  • 0
    Я делаю олдскульно — exim4 с транспортом, заворачивающим всё в локальный maildir:

    begin transports
    
    development:
     driver                  = appendfile
     user                    = username
     group                   = username
     mode                    = 0660
     mode_fail_narrower      = false
     delivery_date_add
     envelope_to_add         = true
     return_path_add         = true
     directory               = /path/to/maildir
     maildir_format
     create_directory        = true
    
    ...
    
    begin routers
    
    development:
     driver                  = accept
     condition               = 1
     transport               = development
     no_more
    


    Для чтения пользуюсь mutt или (если нужно посмотреть html) evolution.
  • +1
    sudo apt-get install -y vim curl python-software-properties lynx nginx
    sudo apt-get install -y php5-fpm php5-memcache memcached php-apc

    Господи, зачем это все?

    Даже не думал, что из команды gem install mailcatcher можно сделать целую статью.
  • 0
    Насколько надо быть расслабленным, чтобы такие проверки выполнять, не проверив дважды? Я бы для начала проверил на собственном почтовом ящике.
    • 0
      Хм, ну это пример в статье, но на самом деле всякое бывает. Вот буквально позавчера мы узнали о баге в рассылке, используя MailCatcher мы бы её увидели на этапе тестирования, а так — прощёлкали :(

      Собственно, почему я и стал искать информацию о подобном софте, наткнулся на MailCatcher, на русском информации нет, решил поделиться тем что есть. Т.е. тут акцент не на том КАК его поставить (DarthSim), а на том, что такое ЕСТЬ в принципе и совсем не замороченное в использовании.
      • 0
        Вообще – согласен, если ещё не было установлено чего-то подобного в системе рассылок – это упущение, однозначно.
        Но акцент подачи текста я бы сместил в сторону упрощения тестирования, а не исправления ошибок тестировщиков.
    • 0
      Проверять нужно не только одно письмо. Недавно из-за досадной ошибки во всех письмах хэш в ссылке для отписки оказался один и тот же (от первого подписчика), если бы, не потыкал пару раз в случайно выбранных письмах в ссылку отписки, никто бы баг и не заметил. Хотя… Тогда и отписавшихся бы не было))
  • 0
    Выходит, на одного пользователя приходится два почтовых клиента у нас на планете?
    • 0
      Дома на пк/ноутбуке, на работе, в телефоне. В 2014 г. эти числа, я думаю, еще подросли.
  • 0
    Еще вариант:

    python -m smtpd -n -c DebuggingServer localhost:8888
    
    • 0
      Этот вариант просто печатает письмо в stdout. Удобно проверять сам факт что письмо отправилось, а вот смотреть контент письма, особенно в HTML уже не так удобно.
      • 0
        Не пробовал сам, но, навскидку, нельзя ли прицепить bcat для просмотра в браузере?
        Напиример, как-то так:

        python -m smtpd -n -c DebuggingServer localhost:8888 | bcat
        
        • +1
          Даже не знал про такую утилиту. Сейчас специально попробовал — видимо есть какая-то проблема с буфером. Надо кинуть несколько сообщений чтобы они появились в браузере, последнее может быть обрубленное. Ну и HTML либо не рендерится, либо в случае с bcat -h некрасиво показываются заголовки.

          Так что для удобной работы надо еще разделять сообщения друг от друга и разделять заголовки от контента (или даже контентов).

          В общем mailcatcher.me, mailtrap.io и debugmail.io делают нечто большее, чем DebuggingServer
  • 0
    Если делать конфиг на puphpet.com то можно подключить MailCatcher в пару кликов. Развернуть полученный конфиг можно в Vagrant, а также в Amazon и DO
    • +1
      Так точно, именно поэтому я и упомянул об этом в примечании.

Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.