0

I have a method that runs with Selenium to create user accounts on a website quickly. Currently it processes one after the other, but I'm thinking if I can process 10 at once that would be better.

I have a for loop currently, which is used to tell the code within, which line of my 2D array to read the user information from. I am struggling with the concept of how to make any stream or thread use the correct value and fetch the correct user information.

Currently I have something similar to the below simplified:

I need to load a new page and driver everytime this loops and need to send the value of the array to the web field. So basically I want this to go off and loop and not wait for the first loop to finish before starting the next loop, but probably limit to 10 or so running at once.

for(i=0,i<myarray.length, i++) 
{ 
      Webdriver.start();
      WebElement.findby.(By.name("field1").sendkeys(myArray[i][2]);
      Webdriver.end();
} 

As I said code is not actual code it is just to get my question across.

Hope that is clear.

Graeme Wilkinson
  • 419
  • 5
  • 12

2 Answers2

1

I think you're saying, I am iterating through myArray and running my test once for each element in that array, but instead of running one test and waiting for it to finish before running the next, I want to run a whole bunch at a time.

You can do this pretty trivially with the Java 8 ForkJoinPool.

ForkJoinTask[] tasks = new ForkJoinTask[myarray.length];
for(i=0,i<myarray.length, i++) 
{ 
    int j = i; // need an effectively final copy of i
    tasks[i] = ForkJoinPool.commonPool().submit(() -> {
        Webdriver.start();
        WebElement.findby.(By.name("field1").sendkeys(myArray[j][2]);
        Webdriver.end();
    });
}
for (i = 0; i < my array.length; i++) {
    tasks[i].join();
}

The tests will run in parallel using threads from the "common" ForkJoinPool. If you want to adjust the number of threads that are used, create your own ForkJoinPool. (See this question for more information.)

Community
  • 1
  • 1
Willis Blackburn
  • 8,068
  • 19
  • 36
  • sorry, perhaps I wasn't clear, or perhaps I was and your answer addresses this well. So I am using the array like a table in Excel, so the users data is across one row of the array in many columns. I need to start a new web driver for each test, and there is an array of tests running off different columns for each row. if I make this a list, then I may struggle to identify which string in the list is for that particular user? – Graeme Wilkinson Dec 31 '16 at 01:47
  • 1
    Okay, forget about the list. I'll update the answer. – Willis Blackburn Dec 31 '16 at 01:54
1

I would explicitly start separate Thread for every task as the most of time will be likely spent on waiting until the user account is created.

Please, see the code snippet with rough example below:

public void createAccounts() throws InterruptedException {
    List<Thread> threadList = new ArrayList<>();
    Object[][] myArray = new Object[1][1];
    for(int i=0; i<myArray.length; i++) {
        final int index = i;
        //Add thread for user creation
        threadList.add(new Thread(new Runnable() {
            @Override
            public void run() {
                Webdriver.start();
                WebElement.findby.(By.name("field1").sendkeys(myArray[index][2]);
                Webdriver.end();
            }
        }));
    }
    //Start all threads
    for (Thread thread : threadList) {
        thread.start();
    }
    //Wait until all threads are finished
    for (Thread thread : threadList) {
        thread.join();
    }
}
Anton Dovzhenko
  • 2,399
  • 11
  • 16