Automated Testing E-Mail with Neptune
Late last month I made a post about testing E-Mail functionality with Donovan Brown's Neptune. Several of you made comments about other utilities and methods that may be used to test SMTP (that's E-Mail for those of you in Rio Linda) facilities in your .NET applications. Since meeting Donovan I have been making a concerted effort to leverage the automated testing facilities available in Visual Studio Team Edition.
For this entry I am going to leverage the contact form I have been using this year to demonstrate my Thin ASP.NET principles. I added some new files to the web site: testemail.aspx, jQueryContactwEMail.js and ContactHandlerwEmail.ashx. I did this to isolate this from the client-side concepts I have examined to far. The primary difference in these files from the previous example is the addition of a SendMsg method. This method handles sending messages using the built in SMTP facilities of the System.Net namespace.
Thensmtp.Host = vSMTP
NewMailMessage(sFrom, sTo, sSubject, sMsg)
AsSmtpStatusCode = exc.StatusCode
If(statusCode = SmtpStatusCode.MailboxBusy
Or_ statusCode = SmtpStatusCode.MailboxUnavailable
Or_ statusCode = SmtpStatusCode.TransactionFailed)
I have incorporated a little trick explained my Lee Dumond on dealing with a fussy target SMTP server. I like this solution as a simple way to deal with a common scenario when the destination SMTP server just cannot process the request.
Neptune Validation Rules
The features that set Neptune apart from the other solutions is the built in testing components. In particular a set of custom validation rules that work with Neptune to verify expectations were met sending a message or messages. If you are not familiar with Web Test Validation Rules or Creating one, visit these links; Validation Rules, Custom Validation Rule. These are the custom Neptune Validation Rules:
- EMail Find Text ' Verifies a specified string is in the message body.
- EMail Message Count ' Verifies the number of e-mails in Neptune matches an expected count.
- EMail Sender ' Verifies the message's From address matches the expected address.
- EMail Recipient ' Verifies the message's To address matches the expected address.
Neptune Email Reset Plug-in
In addition to custom validation rules Neptune also includes a custom Web Test plug in to automatically reset Neptune's stored messages to zero.
Applying Netptune's Testing Tools
Now that I have explained the code to send an E-Mail and a quick overview of Neptune's testing tools, I want to pull it all together. The first step is to create a new Web Test. You can watch this video to get you familiar with the process if you have not created one before.
The first tool to add is the Email Reset Add-In. There is one property you need to set, Run Before needs to be set to true, as shown in the figure.
Next we want to add all four of the Neptune Validation rules; Find Text, Sender, Message Count and Recipient. The Find Text validation rule needs a string to search for. I chose to look for 'this is a test', since I entered that in the Comment field in my Web Test recording.
I set the Email Count rule to look for 1 message, since the code should only send one message. The Email Sender should be set to 'email@example.com', since this is the from address used by the code. And similarly the Email Recipient is set to 'firstname.lastname@example.org'. These validation rules will automatically call into Neptune to verify these values. If they don't match then the web test request will fail and you can look into why and make corrections.
I know this was a quick example demonstrating the testing features included with Neptune, but I hope you can see the advantage it offers. Even if you don't have the Team System Edition of Visual Studio, where you can use Web Tests, you can also hook into Neptune in unit tests. I hope to start writing more about using not only automated web tests, but also unit testing in Visual Studio in the coming months.
I will be posting the new source code over the weekend, so check back for a new URL.
I have published the source to this series on CodePlex. Go to the Source tab to get the latest source code. I decided to post it there so I could just keep updating as I progressed in this series. I have many great things planned to walk you through in the coming weeks!