November 23, 2019

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

  November 23, 2019
What happens 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 test and in between we need to do a specific step multiple times.

So 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 to our test class containing the code or method to multi thread.

Below is the class in which i have implemented the Runnable class and lets 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 broken link checker scenario. we can use this same logic to automate anu scenario faster.

Issues faced

We may face several issues while using the multi threading in java, because in selenium we are creating only once 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 same through out the execution.

This is handled by testing frameworks like Mstest , TestNG while parallel execution.
But when we are using the multithreading these object may to be able to write more that one set data at 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 set of output results from 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 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());
  }
 }

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

This kind of workarounds we can think about in 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

Fixing javascript error: Cannot read properties of null (reading 'querySelector') issue when using CSS identifier in selenium

 JavaScript is another way to interact with web elements when normal selenium methods fail to act. But one issue with javascript is, it does...