Emailing functionality is something that a lot of applications feature to their users. They can either send emails to the users or process emails received from users. If you don’t take care of your environment isolation or do not use some special tools you are under the risk of serious impact on your company or your customers. What we’re going to talk about is actually applicable to both automated and manual testing. However here we’ll be concentrating on manual testing aspects.
Usually applications implement emailing capabilities in one of two ways:
Use third-party services. This option is often used by publicly exposed applications. The reason is that there could be really lot of users subscribed to your emails and you might want to gather some statistics about them, perform some analysis and also you might not want to care of whether your email be considered as spam, etc. All those issues can be addressed by a special mailing services. Your application might interact with such services using REST API or other interfaces.
Use a dedicated SMTP, POP3, IMAP servers, that your application would be configured for. This option is more often used for internal web applications where there are no special requirements for managing the subscribers and analyzing their dynamics.
The latter one is the subject of this article. Here we’ll see the example of how you can deploy and use GreenMail tool in order to make sure your email environment is isolated and fully-featured from email protocols standpoint.
Why testing emailing with real SMTP server is bad idea
You can read the introduction above and say: "Hey, we’ve always been testing our emailing using the corporate SMTP server and never went into issues! So, what’s wrong now?". Well, you’re lucky enough then. Actually I would point out several reasons why you shouldn’t do so:
First and the most important one is the question of security. When you test email functionality you can accidentally involve real user emails into your test messaging. This might lead to either customer sensitive data leakage or your company sensitive data leakage to third parties.
Useless but heavy payload onto your corporate infrastructure. If your application sends a lot of messages in a small amount of time, there is a high chance that your infrastructure that you share with your colleagues will get overheat.
You may run out of resource quotas (such as disk storage, etc.) that is configured for you and those who share SMTP, POP3 and IMAP servers with you.
Hence by using a dedicated mail server mock that is easily to configure and manage one may improve the reliability and effectiveness of testing email features.
In this example we’re download and run GreenMail email sandboxed mail server that supports SMTP, POP3, IMAP protocols and their TLS wrappers. We’ll concentrate on the first two protocols not to overwhelm the article.
We’ll see how to create user accounts at that server, how to send and receive emails with a popular Mozilla Thunderbird email client (the knowledge of how to manage things in Thunderbird is easily to transfer to any other email client).
There is the only prerequisite for you before you can start. The server is written in Java language so that you have to have JRE installed. The path to your JRE executable (in order to be able to run
java command from anywhere) has to be present in
PATH environment variable. Optionally you need to make sure that the ports you’re going to use for hosting email services are available and accessible from any required place of your network (otherwise you’ll only be able to work with the service using
localhost loopback interface).
Quick start with GreenMail
As I have mentioned before, GreenMail is a Java program. Thus, it is distributed as
jar archive (a binary). It is worth saying that GreenMail is distributed in several different packages. Depending on your particular need, you can download binaries to use them as a part of your test solution so that you manage your server right from your code, or as a standalone solution so that you can run its self-sufficient executable archive. It can be available to more people, can be integrated with the tests, written in different languages (not only Java), take less time to start everything up, and in general have a higher degree of availability to everyone.
Since this article is related to #manual testing, we’re not going to manage everything from code. We’re not even going to write any line of code. We’ll be working with standalone package. You can find the latest builds at this official GreenMail download page. Download the binary that is against GreenMail Standalone, but don’t touch "Docker Hub" link. Save the downloaded
jar file to some folder that is now to host our GreenMail server.
Now change current folder to one that you have chosen for storing executable
jar of standalone package. Execute:
java -Dgreenmail.setup.test.all -jar greenmail-standalone-1.5.11.jar
java- tells that you are going to execute Java application
-Dgreenmail.setup.test.all- one of the ways how Java application can get some information from the outside. It is called system property.
-Ddefines a property as
greenmail.setup.test.allis the name of the property. You can find more properties which GreenMail supports using this GreenMail documentation. We’ll cover some of them later on here. This particular property enables all the supported protocols bound to their well-known ports but shifted to
3000. Hence, SMTP will be bound to
3025, POP3 to
3110and so on.
greenmail-standalone-1.5.11.jar- name of binary file of GreenMail standalone that I’m using in this article (the latest version by the moment), but in your case it may differ.
If you need to run only specific mail services on the default "test" ports you need to run the following command:java -Dgreenmail.setup.test.smtp -Dgreenmail.setup.test.pop3 -jar greenmail-standalone-1.5.11.jar
Where you basically run only SMTP and POP3 protocols on
The command above will start some quick configuration of GreenMail that won’t have issues unless you either have mentioned ports occupied by some other processes or need to connect to your server from some outer machine. To fine-tune your server you will need to add more properties when execute the service.
Tuning service host and ports
If you are not satisfied with the ports which are assigned to the services when you set
-Dgreenmail.setup.test.all property or you would like to connect to your mail stub from some different host of your network, then you can use more properties to set more specific port and host for each of service or not run some services at all.
When you pass system properties to your application that is executed as executable jar you should list all the properties before you specifying
jarfile in your command line. Like this:
java -Dprop1 -Dprop2 … -DpropN -jar yourexecutable.jar
If in some reason you need different ports to host your mail services, then you can combine the properties which are to address such goals. There are few things to remember:
Each service (protocol) has to have bound to some ip address and some port
There is a default host binding:
127.0.0.1. However that will allow you to only connect to the services from localhost. If you need to connect from other computers of your network it is better to set up default host to
0.0.0.0. There is a dedicated property for that. For example:
You can omit explicit host specification since there is a default value but you cannot omit port specification. Port number is configured per protocol and the property would look like
-Dgreenmail.PROTOCOL.port=1234. The example could be the following:
Much like port number you can bind different protocols to different hosts. Use the following approach:
-Dgreenmail.PROTOCOL.hostname=126.96.36.199. The example could be
Any specific value for protocol overrides general value. So that if you have default host name, you can set some specific host for certain protocols. In the same manner if you use
-Dgreenmail.setup.test.allthat configures default values for everything, you can still override values for some particular protocols. Below are several examples of how we can start GreenMail and what the configuration would be eventually.
-Dgreenmail.hostname=0.0.0.0 -Dgreenmail.setup.test.smtp -Dgreenmail.setup.test.pop3
The example above sets up default test configs for SMTP (
-Dgreenmail.setup.test.smtp) and POP3 (
-Dgreenmail.setup.test.pop3) protocols but overrides ip address binding (
-Dgreenmail.hostname=0.0.0.0) so that both protocols are bound to default test ports but
0.0.0.0 ip address that allows to use them from outside. No other protocols except of mentioned two are started up.
-Dgreenmail.hostname=0.0.0.0 -Dgreenmail.smtp.port=12345 -Dgreenmail.setup.test.pop3
The example above starts GreenMail that has two protocols enabled: SMTP that is started on
12345 port and POP3 that is sstarted on default test port
3110. Both are bound to
0.0.0.0 so that is is available from the outer network.
The example above shows the same case as previous one, but both the protocols are bound to
127.0.0.1 so that they can only be used from local host.
The example above demonstrates how to start GreenMail if you need only SMTP service that is to be available for only local connections
-Dgreenmail.smtp.port=12345 -Dgreenmail.smtp.hostname=0.0.0.0 -Dgreenmail.pop3.port=1110
The example above runs SMTP and POP3 protocols which are both available for outer connections and which are both running on specific (non-default) ports.
GreenMail is a sandboxed service that is not intended to persist its state after shutting down. After all it is not fully featured email service but something that is extremely useful for testing. If you sent some mails and if you had some users on the server then everything will be lost after reboot. But how do we set up users on that server? There are two ways how the users appear in GreenMail.
First way is configuring users through a system property much like we can configure the protocols, ports, ans so on. There are several patterns for configuring users. I prefer to use this one:
The system property
-Dgreenmail.users is just added to other properties which configure other aspects of your server. Despite you can create a user with only SMTP protocol enabled, for the further demonstration (connect with email client) we will need incoming email protocol also enabled. Hence with the following set of properties we can enable SMTP and POP3 protocols and set up some test account for them:
-Dgreenmail.smtp.port=12345 -Dgreenmail.pop3.port=54321 -Dgreenmail.users=testacc:firstname.lastname@example.org
The example above will start SMTP and POP3 protocols available for only local connections and set up a user which has
testacc account name that has
testpwd password and that account is associated with
Second way is when you send an email to someone that does not exist on the server. If the email is sent through SMTP service of GreenMail, and there is no associated account for that email, then the account is created automatically. In that way account name is just equal to the email address (unlike the previous approach where account name and email are different things). The password in turn is the same as the account name and obviously the same as email address. We’ll take a look at that more closely in the next chapter.
Connect to GreenMail with mail client
Your tests wouldn’t be reliable and effective if you wouldn’t be able to send and receive emails through some email client. In this paragraph we’re going to use Mozilla Thunderbird in order to connect to GreenMail, send and receive emails. We’ll also demonstrate how new users are created in end-to-end flow.
Here I assume that you have Thunderbird already installed so that we do not start from scratch. Lets run both SMTP and POP3 protocols (local connections would be enough for the demo) as we have done that in previous examples:
java -Dgreenmail.smtp.port=12345 -Dgreenmail.pop3.port=54321 -Dgreenmail.users=testacc:email@example.com -jar greenmail-standalone-1.5.11.jar
Here you should see some output if you are not detaching your console from the executed server (I believe that if you carefully followed my examples then you are not). The output is informative enough despite it is not in verbose mode (that can be enabled with dedicated system property). From the output we can find out which protocols are executed on which ports and bound to which ip addresses. Now we can configure our mail client to work with the running instance of GreenMail.
Click [Email] button under "Set up an account". There you will see the dialog to configure your email account. What you will see is actually implies that Thunderbird will do everything automatically for you, however we do not have a real email infrastructure so that we’ll have to configure everything manually. Type in your name, account name, email and password. You can set any name, but you have to set other fields corresponding to what we set up when executed our server. Remember, account name is
testacc, password is
testpwd and email is
firstname.lastname@example.org. After you have set up everything click [Manual config] button.
Now you can specify our custom connectivity settings. The only fields you need to change is what is outlined with orange line. Change incoming protocol to POP3, change server hostnames for both the protocols to
localhost, change the ports to the ones we specified when executed our server:
54321 for POP3 and
12345 for SMTP. Click [Re-test] button. SSL and Authentication properties will be queried from our server and set up automatically.
Now click [Done] button. You should see the warning saying that the server does not use SSL encryption. Check "I understand the risk" checkbox and then [Done] button. You now have completed account configuration for your
testacc account. You can send and receive messages.
Q: I have sent an email to the address that really exists. Will the real addressee receive it?
A: No. It won’t receive your email because GreenMail is sandboxed. The email will only be living inside GreenMail. If you’re sending the email to that address for the first time, then new account will be created to store it.
If you click [Get Messages] button nothing will be downloaded because neither a human nor a process sent anything to your new account. Let’s write some email to non-existent address.
Click [Write] button. You will see email editor. Set some non-existent address to
To: field. For example that address could be
email@example.com. Set some subject and write some text in body. Then click [Send] button. If you look to the console window where you started GreenMail server, you should see something like this:
"Created user login firstname.lastname@example.org for address email@example.com with password firstname.lastname@example.org because it didn’t exist before"
This means that we can repeat the steps we were doing for our
testacc with some small difference. That time our account name was what preceded
@ symbol. Now there is different case. The whole email address is the account name, hence we have to change some more fields this time, like it is shown below:
Fields which are pointed with the arrows (plus the email field itself) have to contain the account email (i.e.
email@example.com) as their values. Once you have confirmed all the further dialogs you will see that you now have one more account set up in your Thunderbird client. You will also see that there is one email in inbox folder of your new account. That email is exactly what we have recently sent to it.
Now you know how to set up test email infrastructure so that you’re not under the risk of data leakage or other harmful impact on your company or your customers. If you still have the questions please send them to me using this form. I will amend the article according to your feedback.