Как протестировать рассылку почты

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

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

  1. установить почтовый прокси и настроить приложение (или php) на отправку почты через него
  2. использовать специальный почтовый транспорт.

Фактически, первый вариант может удовлетворить в большинстве случаев. Но чтобы им воспользоваться, нужно вмешиваться в операционную систему — устанавливать скрипты или приложения, вносить изменения в php.ini. Часто это не представляет проблемы, но не всегда.

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

В Zend Framework есть специальный компонент, отвечающий за рассылку почты — Zend_Mail. Этот компонент предоставляет единый интерфейс для различных почтовых транспортов (таких как php-функция mail или прямое соединение с smtp-сервером). Написать собственный транспорт не составляет большого труда, что, собственно, я и сделал.

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

Для того, чтобы проверить содержимое генерируемых нашим приложением писем, я написал небольшой почтовый транспорт. Код транспорта можете посмотреть и скачать с github-а, а далее я покажу как им можно воспользоваться. Но перед этим я хочу остановиться на возможностях этого транспорта:

  • работа в двух режимах:
    • имя файла дампа постоянно при отправке нескольких писем
    • имя файла генерируется для каждого письма индивидуально
  • возможность сохранения данных как с перезаписью, так и с дописыванием в конец существующего файла
  • письма сохраняются в файлы формата *.eml, что позволяет посмотреть их в почтовом клиенте
  • возможность использовать собственную функцию для генерации имени файла письма

А теперь вернемся к использованию транспорта.

Чтобы указать Zend_Mail каким образом следует отправлять почту, следует передать экземпляр нужного транспорта в метод отправки почты (см. документацию).

Во-первых, указываем автолоадеру пространство имен:

# application/config/application.in
autoloaderNamespaces[] = "bpLib_"

Во-вторых, перед вызовом метода send Zend_Mail-а создадим экземпляр файлового транспорта:

$transport = new bpLib_Mail_Transport_File(
        '/tmp',
        bpLib_Mail_Transport_File::MODE_REGULAR
);

Конструктор файлового транспорта принимает 3 параметра:

  • путь к каталогу, в который будут сохраняться письма
  • режим работы (имена постоянные/меняющиеся; дозапись/перезапись)
  • имя callback-функции

По первому параметру, я думаю, все ясно, поясню остальные. Режим работы задается маской — в нулевом бите режим формирования имен файлов, в первом режим записи в файл. Таким образом существует три варианта:

  • bpLib_Mail_Transport_File::MODE_REGULAR — для постоянного имени файла с перезаписью содержимого файла
  • bpLib_Mail_Transport_File::MODE_REGULAR | bpLib_Mail_Transport_File::MODE_APPEND — для постоянного имени файла с дополнением файла
  • bpLib_Mail_Transport_File::MODE_RANDOM — для индивидуальных имен файлов у каждого письма

Четвертый вариант (индивидуальные имена с дополнением файла) хоть и возможен, но бессмыслен.

Третий параметр представляет собой название callback-функции, вызываемой для генерации имени файла. Формат параметра аналогичен функции call_user_func_array. Внутрь функции передается экземпляр транспорта. Таким образом, функция имеет доступ ко всем данным письма: заголовки, тело, вложения, что позволяет генерировать имена файлов в зависимости от содержимого письма. В качестве примера приведу метод, используемый по умолчанию:

protected function randomFilename()
{
    return date('Y-m-d-H-i-s').'-'.rand(10000,99999).'.eml';;
}

Ну и наконец передаем созданный нами экземпляр транспорта в метод send:

$mail = new Zend_Mail('UTF-8');
$mail->setSubject("SUBJECT")
    ->addTo('recipient@mail.com')
    ->setFrom('from@mail.com', 'From User')
    ->setBodyText("some text...")
    ->send($transport)
    ;

Собственно это все, что нужно для использования.

К сожалению, нельзя подключить этот транспорт в качестве основного в файле настроек приложения, т.к. ресурс, отвечающий за почтовый компонент, ориентирован исключительно на транспорты Zend Framework-а. Но выход из положения есть! Можно в файле начальной загрузки написать метод, устанавливающий файловый транспорт в качестве транспорта по-умолчанию:

$transport = new bpLib_Mail_Transport_File(
        '/tmp',
        bpLib_Mail_Transport_File::MODE_REGULAR
);
Zend_Mail::setDefaultTransport($transport);

На этом я пожалуй закончу описание транспорта. Возможно в одной из следующих заметок я опишу как можно установить и настроить почтовый прокси.

До новых встреч!

google.com bobrdobr.ru del.icio.us technorati.com linkstore.ru news2.ru rumarkz.ru memori.ru moemesto.ru
Print
1 звезда2 звезды3 звезды4 звезды5 звезд (2 голосов, средний: 5.00 из 5)
Loading ... Loading ...

Метки: , , , , , ,



13 комментариев на “Как протестировать рассылку почты”

  1. lcf пишет:

    Проведя небольшое исследование, решил что можно пойти двумя путями:

    1 установить почтовый прокси и настроить приложение (или php) на отправку почты через него

    2 использовать специальный почтовый транспорт.

    Это не совсем так, есть еще 3ий путь — использовать любой другой почтовый сервер. Например зарегестрировать dev акк гугло почты, передать логин пароль в Zend_Mail_Transport_Smtp и... всё, можно тестировать.

    Однако, я вижу приведенное тут решение весьма и весьма удобным в ряде случаев. Думаю подрихтовать и выйдет отличный пропозал. Не хочешь попробовать?

    • Лобач Олег пишет:

      Например зарегестрировать dev акк гугло почты, передать логин пароль в Zend_Mail_Transport_Smtp и... всё, можно тестировать.

      «dev акк»? Это что за аккаунт такой? Никогда не встречал. Где о нем пишут?

      Думаю подрихтовать и выйдет отличный пропозал. Не хочешь попробовать?

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

      Кстати, возможно лучше переименовать в ..._Debug вместо ..._File

    • Лобач Олег пишет:

      Думаю подрихтовать

      А что именно подрихтовывать надо?

  2. lcf пишет:

    «dev акк»? Это что за аккаунт такой? Никогда не встречал. Где о нем пишут?

    Ну образно, имееться в виду тестовый аккаунт. Берете любой бесплатный сервис почты, например gmail. Регистрируете почту.

    Например разрабатываешь ты mysupersite.com, регистрируешь почту dev.mysupersite@gmail.com для всячесих изощерений, оно по идее пригодиться не только для этого.

    Берешь Zend_Mail_Transport_Smtp, передаешь туда логин пароль, настройки сервера smtp (хост порт, для гугла например smtp.gmail.com, 465), всё, можно тестировать отправку почты, ничего не надо устанавливать и писать. Понятно?

    А что именно подрихтовывать надо?

    Я имею в виду оформить код нормально, по аккуратнее и в соотвествии со стандартами ЗФ. В принципе это дело десятой потому что кода пару строк, главное — идея. Насчет переименовывания File в Debug пожалуй можно, думаю комьюнити выскажется по этому поводу если сделаете пропозал.

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

    Не думаю что тут нужно много тестов, поэтому это мне и видиться привлекательным пропозалом — просто и со вкусом :) В принципе если ты согласен то я готов сделать все остальное, заполнить пропозал, исправить (совместно) все что попросят. Если у тебя есть CLA подписанный, то просто сделаем пропозал на двоих, или если нету — тогда можешь подписать и добавим тебя в список пропозеров когда ответ придет. Если не согласен, то можно скооперироваться в другом виде, предлагай. С составлением английских текстов необходимого уровня у меня проблем нет.

    • Лобач Олег пишет:

      всё, можно тестировать отправку почты, ничего не надо устанавливать и писать. Понятно?

      Да, понятно. Этот способ не шибко хорош тем, что осуществляется фактическая отправка писем, а это не всегда допустимо. Например, если тестируется функционал на реальных адресах пользователей, тогда рассылать просто недопустимо, а проверить надо.

      Либо я что-то все же не понял

      • lcf пишет:

        Да, для рассылок, когда надо проверять не как генерируюца письма, а и то как они и куда уходят, ваш транспорт как раз и пригодиться.

    • Лобач Олег пишет:

      Я имею в виду оформить код нормально, по аккуратнее и в соотвествии со стандартами ЗФ

      Хм... я вроде старался по стандартам код писать. Ну разве что шапки phpdoc-а на зендовские заменить. Но готов остальное оформление поправить, если есть такая необходимость

    • Лобач Олег пишет:

      Не думаю что тут нужно много тестов, поэтому это мне и видиться привлекательным пропозалом — просто и со вкусом :)

      Если ты про модульные тесты, то они есть (в гитхабе можешь посмотреть). Возможно они требуют доработки...

      В принципе если ты согласен то я готов сделать все остальное, заполнить пропозал, исправить (совместно) все что попросят. Если у тебя есть CLA подписанный, то просто сделаем пропозал на двоих, или если нету — тогда можешь подписать и добавим тебя в список пропозеров когда ответ придет.

      Нет, я не против. Подписанного CLA у меня нет.

      • lcf пишет:

        Если ты про модульные тесты, то они есть (в гитхабе можешь посмотреть). Возможно они требуют доработки...

        Сорри, опечатка, «тексты» я имел в виду.

      • lcf пишет:

        Окей, тогда я подготовлю пропозал базовый (возможно будет время сегодня или на выходных) и скину ссылку тебе на ознакомление и внесение правок.

        Я так думаю надо уже под зф2.0 пропозал делать, надо будет это уточнить.

        • Лобач Олег пишет:

          Окей, тогда я подготовлю пропозал базовый (возможно будет время сегодня или на выходных) и скину ссылку тебе на ознакомление и внесение правок

          Ок. Буду ждать

Оставить комментарий