November 23, 2019

How to Enable multi-threading in selenium java for faster execution

  November 23, 2019
What happens if we have one test and when we start the test then we need to do a specific set of steps in parallel.
This absolutely looks like a requirement any automation tester would face.

So our execution starts from the main class (or test method), and even if enable the parallel execution is enabled we will be executing the whole class in parallel.

So our case is like this, we have started the execution of the test and in between, we need to do a specific step multiple times.

To do this in minimum time we can use the multi-threading functionality of Java.

For this to implement we need to use the Runnable class of Java and implement it in our test class containing the code or method to multi-thread.

Below is the class in which I have implemented the Runnable class and let's see how it's done.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
package test.package;

import java.io.File;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import org.openqa.selenium.WebElement;

public class LinkChecker implements Runnable {
 private final String url;
 private static final int MYTHREADS = 60;

 public LinkChecker(String url) {
  this.url = url;
 }

 @Override
 public void run() {

  String result = "";
  int code = 0;
  try {
   URL siteURL = new URL(url);
   HttpURLConnection connection = (HttpURLConnection) siteURL.openConnection();
   connection.setRequestMethod("GET");
   // connection.setInstanceFollowRedirects( false );
   connection.setConnectTimeout(6000);
   connection.connect();

   code = connection.getResponseCode();
   if (code == 200 || code == 301 || code == 302) {
    result = "-> Green <-\t" + "Code: " + code + " - " + connection.getResponseMessage();

   } else {
    result = "-> Yellow <-\t" + "Code: " + code + " - " + connection.getResponseMessage();
   }
  } catch (Exception e) {
   result = "-> Red <-\t" + "Wrong domain - Exception: " + e.getMessage();

  }

  String res = url + "   Status: " + result;
  System.out.println(res);
  try {
   Thread.sleep(500);
  } catch (InterruptedException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
 }

 public void DisableSSLChecking() {
  TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
   public java.security.cert.X509Certificate[] getAcceptedIssuers() {
    return null;
   }

   public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType) {
   }

   public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType) {
   }
  } };

  // Install the all-trusting trust manager
  try {
   SSLContext sc = SSLContext.getInstance("SSL");
   sc.init(null, trustAllCerts, new java.security.SecureRandom());
   HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
  } catch (Exception e) {

  }
 }

 public void CheckAllURLS(List<String> links) {
  DisableSSLChecking();
  System.out.println("Total links are " + links.size());

  ExecutorService executor = Executors.newFixedThreadPool(MYTHREADS);

  for (String LinkPick : links) {

   String url = LinkPick;
   try {

    Runnable worker = new LinkChecker(url);
    executor.execute(worker);

   } catch (Exception e) {

    System.out.println("Unable to Validate URL " + url);
   }
  }
  executor.shutdown();
  // Wait until all threads are finish
  while (!executor.isTerminated()) {

  }

  System.out.println("\nFinished all threads");

 }

}

From the above example, we can use the method CheckAllURLS and pass the list of URL's to repeat the step in multiple threads.

This example is specific to the broken link checker scenario. we can use this same logic to automate any scenario faster.

Issues faced

We may face several issues while using the multi-threading in java, because in selenium we are creating only one instance of web driver, and the same driver is used to do any action on the browser till the end.
Same thing when we are using reporting tools like extent report , where we create one object of the extent report and use the same throughout the execution.

This is handled by testing frameworks like Mstest , TestNG while parallel execution.
But when we are using multithreading these objects may be able to write more than one set data at a time, So we need to think of some logic before going for multi-threading when webdriver or extent report is in use.

In my case, I had a set of output results from the broken link checker method, when I tried to write the result right after each thread execution extent report did throw an exception. Because there is been multiple results coming to extent report object same time from different threads.

How I handled this is by writing all the results to a text file using the below code.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
 public void fnWriteToTextFile(String sFilePath, String sText) {
  try {
   File file = new File(sFilePath);
   if (!file.exists()) {
    file.createNewFile();
   }

   FileWriter fw = new FileWriter(file, true);
   PrintWriter out = new PrintWriter(fw);

   // Append the name of ocean to the file
   out.println(sText);

   // Close the file.
   out.close();

  } catch (IOException e) {
   System.out.println(e.getMessage());
  }
 }

We can read those results line by line in a single thread and write to extent report once all threads complete the execution.

These kinds of workarounds we can think about in the case of webdriver or any other type of objects also.

logoblog

Thanks for reading How to Enable multi-threading in selenium java for faster execution

Previous
« Prev Post

No comments:

Post a Comment

How to send email from current Outlook instance using Java + VBScript

If we are using .Net, we can easily access outlook and send emails using its own libraries. But what if we are using Java? Here we can seek ...