Gmail API Usage in Test Automation

Test automation with Gmail API will be explained in this article in depth.  I will tell you how to use Gmail API in test automation projects. I am mostly using Gmail API in an automation project to validate emails sent through my company’s system. We can log in to Gmail and check the emails from UI but it takes a lot of time and it’s not a good practice to test Gmail in production. So we are using Gmail API. Let’s start

Enable Gmail API

The first step is to enable the Google APIs and Service. So you need to go to https://console.developers.google.com to activate the API access of the email that you will use in your project. Click ENABLE APIS AND SERVICES. It will take you to the search page.

There, you need to search for GMAIL.

When you select the GMAIL API, you need to push the ENABLE button. It’s so easy right!

Configure Gmail Consent Screen

Now you need to create credentials that you’ll use in the project. Those credentials will give you access to any Gmail services. Select CREATE CREDENTIALS button.

In the next screen, you have to select the OAuth consent screen and select External. If you choose Internal, your app will require verification. Select External and click CREATE button.

Give a name to your application. I added “SWTESTACADEMY” as my project name. There are some already defined Scopes for you. In case you need to do more with Gmail API, just add whatever suite your need. For this tutorial, default ones are ok.

Congrats, you just configured the consent screen that you will need once in the project.

Create GMAIL Credentials

Now, navigate to the Credentials page once again. Select CREATE CREDENTIALS on the top menu. Then select the OAuth client ID sub-menu.

Choose Desktop App and give a name. I once again give the swtestacademy name. In case you are going to use Gmail in a different project you need to select a different app type like Android, TV app, etc..

Hit SAVE button. Here you go, your credentials are ready.

Now download the credentials by using the Download Icon next to the OAuth 2.0 Credentials. A JSON file will be downloaded. I will tell you how you are going to use this JSON.

Create a Java-Maven-Gradle Project

I create a Gradle project, you can change the dependencies according to your environment. Below dependencies are the only one I need for this tutorial.

dependencies {
    compile 'com.google.api-client:google-api-client:1.23.0'
    compile 'com.google.oauth-client:google-oauth-client-jetty:1.23.0'
    compile 'com.google.apis:google-api-services-gmail:v1-rev83-1.23.0'
    compile 'javax.mail:mail:1.4.7'
    compile group: 'org.jetbrains', name: 'annotations', version: '15.0'
    compile 'org.jsoup:jsoup:1.13.1'
}

The first thing to do you need to read the JSON file you downloaded in the previous steps and use it to access Gmail API. Here’s my project structure. I added the JSON file under the resources.

I have a string that holds the absolute location of the JSON file.

String CREDENTIALS_FILE_PATH = System.getProperty("user.dir") +
                File.separator + "src" +
                File.separator + "main" +
                File.separator + "resources" +
                File.separator + "credential" +
                File.separator + "credentials.json";

This JSON file is not enough to authenticate Gmail APIs. You also need a StoredCredential file to authenticate. But this file will be created automatically in the same location as your JSON file. I will talk about it later. So you need another String that will hold this StoredCredential file.

TOKENS_DIRECTORY_PATH = System.getProperty("user.dir") +
                File.separator + "src" +
                File.separator + "main" +
                File.separator + "resources" +
                File.separator + "credential";

Here’s the method that will authenticate Google. Those codes are almost exactly the same as in the Gmail example that can be found in Google Developer Console documentation. We are going to use this method to access the Credential object.

 private Credential getCredentials(final NetHttpTransport HTTP_TRANSPORT) throws IOException {

        InputStream in = new FileInputStream(new File(CREDENTIALS_FILE_PATH));
        if (in == null) {
            throw new FileNotFoundException("Resource not found: " + CREDENTIALS_FILE_PATH);
        }
        GoogleClientSecrets clientSecrets = GoogleClientSecrets.load(JSON_FACTORY, new InputStreamReader(in));

        // Build flow and trigger user authorization request.
        GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(
                HTTP_TRANSPORT, JSON_FACTORY, clientSecrets, SCOPES)
                .setDataStoreFactory(new FileDataStoreFactory(new File(TOKENS_DIRECTORY_PATH)))
                .setAccessType("offline")
                .build();
        LocalServerReceiver receiver = new LocalServerReceiver.Builder().setPort(8888).build();
        return new AuthorizationCodeInstalledApp(flow, receiver).authorize("user");
    }

Let’s get the total count of emails that I have in my mailbox. The first two lines are the default snippet to log in the Gmail. So you don’t need to change anything. Then I use Gmail service and get the Threads sent to “me”. Now I have a List object with Thread. I can call the size method and get the total count of Threads.

 public int getTotalCountOfMails() {
        int size;
        try {
            final NetHttpTransport HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport();
            Gmail service = new Gmail.Builder(HTTP_TRANSPORT, JSON_FACTORY, getCredentials(HTTP_TRANSPORT))
                    .setApplicationName(APPLICATION_NAME)
                    .build();
            List<Thread> threads = service.
                    users().
                    threads().
                    list("me").
                    execute().
                    getThreads();
             size = threads.size();
        } catch (Exception e) {
            System.out.println("Exception log " + e);
            size = -1;
        }
        return size;
    }

Now, let’s check if I have an email with a given subject. The first two lines are exactly the same. I get the email list sent to “me” and use setQ method to take a lookup with a given input.

 public boolean isMailExist(String messageTitle) {
        try {
            final NetHttpTransport HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport();
            Gmail service = new Gmail.Builder(HTTP_TRANSPORT, JSON_FACTORY, getCredentials(HTTP_TRANSPORT))
                    .setApplicationName(APPLICATION_NAME)
                    .build();
            ListMessagesResponse response = service.
                    users().
                    messages().
                    list("me").
                    setQ("subject:" + messageTitle).
                    execute();
            List<Message> messages = getMessages(response);
            return messages.size() != 0;
        } catch (Exception e) {
            System.out.println("Exception log" + e);
            return false;
        }
    }

Now, I create a main class to trigger those methods.

public class GmailRunner {

    public static void main(String[] args) {

        GmailService service = new GmailService();
        System.out.println("total count of emails is :"+service.getTotalCountOfMails());

        boolean exist = service.isMailExist("Coolblue invoice");
        System.out.println("Mail 'Coolblue invoice' title exist or not " + exist);

        exist = service.isMailExist("BLABLA");
        System.out.println("Mail 'BLABLA' title exist or not " + exist);
    }
}

Here’s the result.

Total count of emails is :100
Mail 'Coolblue invoice' title exist or not: true
Mail 'BLABLA' title exist or not: false

Note: When you first execute your test, a browser will open. It will navigate to Gmail and you need to enter the credential you use to enable Gmail API and select OK for every question that it asks. This is a one-time thing.

Source Code: https://github.com/swtestacademy/gmail-tutorial

All you need to do is to add your credentials.json file into the project.

1 thought on “Gmail API Usage in Test Automation”

  1. Hi,

    I am also using gmail api for handling test mails, however the stored credential token expires biweekly which makes the cicd runs pretty hard to manage, since each time this happens I have to commit and push the new token to the repo. Is there a way to avoid this behaviour?

    Reply

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.