Deploy local email server mock for testing with GreenMail

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:

  1. 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.

  2. 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:

  1. 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.

  2. 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.

  3. 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.

Example description

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

Where:

  • 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. -D defines a property as system property and greenmail.setup.test.all is 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 3110 and 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 3025 and 3110 ports correspondingly.

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 jar file 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:

  1. Each service (protocol) has to have bound to some ip address and some port

  2. 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: -Dgreenmail.hostname=0.0.0.0.

  3. 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: -Dgreenmail.smtp.port=2025.

  4. Much like port number you can bind different protocols to different hosts. Use the following approach: -Dgreenmail.PROTOCOL.hostname=1.2.3.4. The example could be -Dgreenmail.smtp.hostname=127.0.0.1.

  5. 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.all that 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.

-Dgreenmail.smtp.port=12345 -Dgreenmail.setup.test.pop3

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.

-Dgreenmail.smtp.port=12345

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.

Tuning users

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:

-Dgreenmail.users=account1:pwd1@emaildomain1,account2:pwd2@emaildomain2,...

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:testpwd@webelement.click

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 testacc@webelement.click email.

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:testpwd@webelement.click -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.

GreenMail with mail client Step 1

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 testacc@webelement.click. After you have set up everything click [Manual config] button.

GreenMail with mail client Step 2

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.

GreenMail with mail client Step 3

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.

GreenMail with mail client Step 4

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 testacc@webelement.pleasedontclick. 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 testacc@webelement.pleasedontclick for address testacc@webelement.pleasedontclick with password testacc@webelement.pleasedontclick 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:

GreenMail with mail client Step 5

Fields which are pointed with the arrows (plus the email field itself) have to contain the account email (i.e. testacc@webelement.pleasedontclick) 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.

GreenMail with mail client Step 6

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.