What is this?
Here are a few add-on files for SimpleTest that enable
you to run tests that include checking
for and reading the contents
of emails generated by the system under test.
|
Download
The current version is a first release, 16 Apr 2005:
simplemail-0.1.zip (4.25k)
|
Motivation
I recently had the need to run some automated tests on an e-commerce
website which uses double opt-in
for customer registrations in a
similar manner the the system of Amazon. Testing such a system manually
quickly becomes very annoying because of the need to constantly create
new email addresses, then go through the registration and sign-up
process, checking email, etc. It becomes difficult to test all the
different scenarios because of the time reuqired to perform each manual
test.
I had heard about SimpleTest
and thought that it might have been possible to use it for this. It has
an excellent simulated web browser ('SimpleBrowser') which acts just
like a web browser but is intereacted with via PHP scripts.
Unfortunately it didn't have any corresponding way to simulate a mail
user agent (MUA) such as Mozilla Mail, Outlook, etc. I contacted the
SimpleTest mailing list and I was told about the Fakemail project, but I
thought that a little more work was required to make this integrate
nicely with the SimpleTest testing platform.
The result is a basically functional SimpleMail class which can be
passed a few very simple commands that allow emails to be loaded,
MIME-decoded and read.
|
Example
Here is an example (download) which shows
testing of a double opt-in process:
<?php
require_once("fakemail/fakemail.php");
require_once("fakemail/simplemail.php");
class TestDoubleOptIn extends WebTestCase {
var $_fakemail;
var $emailaddress;
var $password;
function setUp(){
$this->emailaddress = TEST_EMAIL;
$this->password = TEST_PASSWORD;
$this->_fakemail=new FakeMailDaemon(NULL,NULL,10025);
$this->_fakemail->start();
}
function tearDown(){
$this->_fakemail->stop();
}
function testDoubleOptIn(){
$this->get(TEST_SERVER_HTTP);
$this->clickLink("register");
// form should exist with email address box:
$this->assertWantedPattern('#Please provide your email address#i');
$this->setField("email",$this->emailaddress);
if(!MAIL_TEST_MODE){
$this->fail("Server must be in test mode to run this test.");
return
false;
}
$this->clickSubmit('register');
$this->assertWantedPattern("#An email was sent to "
. preg_quote(trim($this->emailaddress))
.
"#i"
);
// Go and check email
$simplemail = new SimpleMail($this->_fakemail);
$simplemail->login($this->emailaddress);
$simplemail->loadMessages();
$msg =& $simplemail->getLatestBySubject('#^New customer#i');
if($msg===false){
$this->fail("Couldn't find 'new customer' email for ".$this->emailaddress);
return
false;
}
$url = $msg->findLinkAfterText("Please click the link below to confirm");
if($url===false){
$this->fail("Couldn't find link in email: ".$msg->error);
return
false;
}
if(!preg_match("#^".preg_quote(TEST_SERVER_HTTPS)."/reg2.php\\?key=#",$url)){
$this->fail("Email link doesn't match expected: $url");
return
false;
}
// Click the email link...
$this->get($url);
$this->assertTitle("Enter your contact details");
// Fill in customer details form
$this->setField("title","Mr");
$this->setField("firstname","Sam");
$this->setField("lastname","Tiger");
$this->setField("address","77 Domestic Bliss St");
$this->setField("city","Sydney");
if(!$this->setField("country","Australia")){
$this->fail("Unable to set 'country' via selectbox");
return
false;
}
$this->setField("telno","999999");
$this->setField("password1",$this->password);
$this->setField("password2",$this->password);
$this->clickSubmit("continue");
$this->assertWantedPattern("#<h1>Thanks for Registering</h1>#i");
}
}
?>
|
Quick Reference
The class SimpleMail has
the following methods:
SimpleMail(&$fakemail)
- Constructor. You need to pass a FakeMail object to this
constructor. The FakeMail object tells SimpleMail where to read the
emails from.
login($email)
- FakeMail captures all SMTP traffic sent to a given host and
port. By specifying the email address to SimpleMail, we are saying that
we are only interested in reading emails sent to the stated recipient.
Note that FakeMail makes no allowance for BCC or CC etc.
loadMessages()
- This method reads the raw text of all emails sent to the
email address since the FakeMail 'capture' directory was last emptied.
So you want to make sure you empty that directory from time to time.
getMailCount()
- Number of emails found for the email address specified
getMessageByNumber($num)
- Load then n-th email address for the specified email address
- getLatestBySubject($subjectpattern)
- This method starts at the most recent email, MIME-decodes
that email then checks the headers for that email. If the
$subjectpattern
is found in the email's Subject: header, the email is
returned as a SimpleMailMessage object. Else the previous email is
tried. If no matching emails are found, the return value is false .
getLatestBySender($senderpattern)
- This works the same way, except it checks the mail's
From:
header.
The class SimpleMailMessage is
a container for a MIME-decoded version of a message captured by
FakeMail. It has the following methods:
- SimpleMailMessage($rawcontent)
- Constructor. Stored the raw content but doesn't decode it.
- decode()
- Makes a call to the PEAR::Mail_mimeDecode class to perform
the MIME-decoding of the raw message content. If decoding runs
successfully, the content is stored in
$this , and $this->rawcontent
is cleared out to save memory.
- getPlainTextVersion()
- This method checks that the main message body is of type
text/plain
and if so, returns the message body. Otherwise returns false .
It is intended that this method be expanded to allow pulling out of the
text version of an email from a multipart/alternative or multipart/mixed
email, but this is not yet implemented. It might also be worth adding
the ability to pull out a strip_tags() version of the
HTML content.
|
What's Next?
- SimpleMailMessage should be able to handle
multipart
and HTML messages
- SimpleMail shouldn't do a full MIME decode of raw message
content when scanning for subject/sender patterns
- SimpleMail shouldn't need to load all those messages into
memory (this would require modification of the FakeMailDaemon class
though).
- Examples and a test suite...
|
Contact Details
If you would like to discuss use of SimpleMail, I suggest you get onto the
SimpleTest mailing list at
http://sourceforge.net/mail/?group_id=76550
Alternatively, you can contact me directly by email:
John Pye <jdpipe at
users.s0urcef0rge.net>
(fix up the zeroes in the domain name)
|
License
This software is licensed under the same terms as SimpleTest
(check the SimpleTest website for details), or, at your option, under
the terms of the GNU
General Public License, version 2.
|
Links
|