Test::Mail - Test framework for email applications


    use Test::Mail 
    my $tm = Test::Mail->new( logfile => $logfile );
    sub first_test { }
    sub second_test { }


Test::Mail provides a framework for testing applications which send and receive email.

A typical example of an email application might send a notification to a certain email address, setting certain headers in certain ways and having certain content in the body of the email. It would be nice to be able to test these things automatically, however most email applications are currently tested by visual inspection of the email received.

Test::Mail allows you to automate the testing of email applications by piping any relevant email through a Test::Mail script.

"Relevant" email is identified by the presence of an X-Test-Mail: header. You should set this email in your application or whatever you use to generate the mail.

    X-Test-Mail: birthday_notification

The value of that header is the name of a subroutine which exists in your Test::Mail script. The subroutine contains Test::More tests to run on the email:

    sub birthday_notification {
        is($header->get("From:"), '', "From address check");
        like($body, qr/Today's Birthdays/, "Email body check");

This allows you to have tests for multiple different kinds of email in one script.

Note that $header and $body are set by Test::Mail for your convenience. $header is a Mail::Header object. $body is the body of the email as a single string. MIME attachments etc are not supported (yet).

The results of the tests run are output to the logfile you specify, and look something like this:

    # test results for birthday_notification for <>
    ok 1 - From address check
    ok 2 - Email body check
    # test results for support_request for <>
    ok 1 - To address check
    not ok 2 - Subject line
    not ok 3 - Included ticket number
    ok 4 - Body contains plain text

Note that while these are roughly similar to normal CPAN test output conventions, counting only occurs on a per-email basis

Sending incoming mail to Test::Mail

To call Test::Mail, simply put a suitable filter in your .procmailrc, Mail::Audit script, or whatever you use to filter your email. Here's how I'd do it with Mail::Audit:

    if ($mail->{obj}->head->get("X-Test-Mail")) {

If for some reason you want to test mail that doesn't already have an X-Test-Mail: header, you could do something like:

    if ($mail->{subject} =~ /test/i) {
        $mail->{obj}->head->add("X-Test-Mail", "subject_auto");

Unaddressed issues

The above is a rough outline of version 1. There are several issues I don't yet know how to deal with, which I'm listing here just in case anyone has any good ideas:

  • Sending output somewhere more useful than a logfile

  • Integrating into a real "test suite" that's friendly to Test::Harness

  • Handling MIME in a suitable way


Test::More, Mail::Header, Mail::Audit


Kirrily "Skud" Robert <>

1 POD Error

The following errors were encountered while parsing the POD:

Around line 187:

=cut found outside a pod block. Skipping to next block.