This is a Katalon Studio project for demonstration purpose. You can download the zip from the Releases page, unzip it, open it with your local Katalon Studio.
This project was developed using Katalon Studiio v7.9.1. But it should work on all KS 7.0+.
This project proposes a new concept TestClosure for Katalon Studio. This project provides a preliminary implementation and demonbstrations as a proof of concept.
Many of Katalon Studio users want to execute multiple test processings parallelly. Me too. They have their own requirements. In my case, I want to take a lot of web page screenshots as quickly as possible.
As I wrote in the README of ExecutionProfilesLoader project, last year I wanted to take screenshots of 6000 URLs. The job took me 6000 * 10 seconds = over 17 hours. Obviously it's too long. I wanted to make the job run faster.
It is a simple job to take a screenshot of a web page.
Open browser, navigate to URL, take screenshot, save image to file, close browser.
Every time we navigate to a new URL, we are forced to wait for a few seconds until the page is fully loaded. This wait makes our sequential processing very slow.
If I have a machine with 8 Core-CPU, I can process these 6000 pages with 8 threads, then the job will be done in 17 hours / 8 threads = 2.2 hours.
But how can I do multi-threading in a Test Case of Katalon Studio?
I know that Katalon Studio offers a feature of executing Test Suites in parallel mode. It isn't satisfactory for me. It is too coarse-grained. I want a way to execute a piece of Groovy scripts in fine-grained / light-weighted Java Threads.
d
It is quite easy to create a Groovy Closure that contains WebUI.*
statements in a Test Case. Executing it is a breeze. See the following example.
When you execute this, you will see a browser window opens, shows a web page, and closes.
java.util.concurrent.ExecutorService
makes conncurrent programming in Java/Groovy much easier. A Groovy Closure implemwents the java.util.concurrent.Callable
interface. You can execute Closures of WebUI.*
statements using ExecutorSerivce
utility in a Katalon Test Case.
The following sample code shows 2 Closures are in 2 threads sequantially in Katalon Test Case.
When you execute this code, you will see 2 browser windows opened/closed sequentially.
I want to parametrize a Closure. I want to execute 2 instances of a Groovy Closure with different values of parameters. The following code shows how to do it. I made a Groovy Class URLVisitor
which implements the java.util.concurrent.Callable
interface. Its constructor accepts parameters.
When you execute this code, you will see 2 browser windows opened/closed sequentially.
Now I want to execute 2 Closures simultaneously, in parallel. The following code does that:
The code difference between this and the previous one is only 1 character. The size of Thread Pool is changed: 1 -> 4.
ExecutorService exService = Executors.newFixedThreadPool(4)
Of course I would expect to see 2 Browser windows to open.
When I executed this example, I got puzzled. I executed 2 threads in parallel, and I saw only 1 window opened. why?
What you see is not what you get, sometimes. The fact is, acutally 2 windows were opened by the script, but the windows were displayed overlayed at the same position (x, y coordinate) with just the same dimension (width, height). So I could see only one. This behavior is very confusing.
I want to manage the layout of browser windows. I want them displayed at different positions (x, y) so that I can see them identifiable. But how can I do it?
WebDriver API provides tools for us to solve this problem. You can explicitly set Window Position and Size. For example,
driver.manage().window().setPosition(new Point(50,200));
and
driver.manage().window().setSize(new Dimension(300,500));
I want to call WebDriver API to set position and size to the windows opened by WebUI.openBrowser('')
call inside the Closures in Test Cases. The following code shows how I managed it.
The framework com.kazurayam.ks.testclosure.TestClosureCollectionExecutor
manages opening/closing browser,
as well as positioning the browser windows. A TestClosure will be pass an instance of WebDriver
as argument. The TestClosure just use the driver.
The TestClosure is not responsible for managing the browsers at all.
Problems are resolved.
You can view the videos by clicking the following links:
demo video | Test Suite elasped (seconds) | what it does |
---|---|---|
demo1A | 27 | visits 3 URLs sequentially, windows are not managed |
demo1B | 30 | visits 3 URLs sequetioally, windows are managed in Tile layout |
demo1C | 55 | visits 5 URLs sequentially, windows are managed in Stack layout, takes screenshots |
demo2A | 20 | visits 3 URLs simultaneously, windows are overlayed at the same (x,y) position with the same width/height |
demo2B | 21 | visits 3 URLs simultaneously, windows are managed in Tile layout |
demo2C | 48 | visits 5 URLs simultaneously, windows are managed in Stacklayout, takes screenshots |
demo3D | 156 | takes Full Page screenshots of 8 URLs using 2 browsers simultaneously. A browser is reused to process 4 URLs each. Unfortunately WebUI.takeFullPageScreenshot() takes long time (approx. 30 seconds each). Unable to post video for demo. |
Using the following environment:
Caution: videos are compressed
When I executed a Test Suite in Katalon Studio to take the demo2A, the Test Suite acutally took 20 seconds to finish processing. But you will find the "movie" plays in 7 seconds. The movie plays far quicker than the acutal scene. I suppose that, while I uploaded the files to Google Drive, the movies were compressed to reduce the size by chomping the still frames off.
A plug-in jar named kazurayam-ks-testobject-x.x.x.jar
is available at the Releases page.
This jar contains com.kazurayam.ks.testclosure.TestClosure
and related classes. Once you install this jar into your project's Plugins
directory,
you can quickly start multi-threading in Katalon Studio.
This project includes a set of working codes. Please read the source to find the detail. The code will tell you everything I could.
Here I write quick pointers:
Have a look at a Test Case that opens 3 browser windows simultaneously:
The code is very short. Is it simple? --- not really. This short code triggers a lot.
Essentially a TestClosure
object is a pair of a Groovy Closure and a list of parameters for the closure. Plus a TestClosure
carries information where the browser window should be located and how it should be sized. The source of TestClosure
is this:
The following Test Case shows an example of creating a list of TestClosure
objects.
The Test Case Test Cases/demo/demo2B_simultaneous_tiling
calles TestClosureCollectionExcecutor
. This object executes the collection of TestClosures
simultaneoutly.
The source code is here:
TestClosuresCollectionExecutor
creates a thread pool of 4 as default. You can change the maxThread by parameter to the Buiilder. The value 1 - 16 is accepted.
This project provides 2 strategies of browser window layout:
TestClosuresCollectionExecutor
uses the Tiling strategy as default. You can explicitly specify the strategy as a parameter to the Builder.
Yes, it does on a machine with 2 or more core-CPU. If my test case executes mutilple TestClosures with multiple threads, it rus faster than with a single thread.
Of course, the faster processing demands more powerful machine resources. If I can afford Mac Book Air M1 with 8-core CPU, my test case with Thread Pool of 8 will run far faster. I want to see it!
It is pointless to give the maximum number of threads for TestClosureCollectionExceutor
with a value larger (8, 16, 32) than the number of cores you have.
I could implement a Test Case that executes multiple Groovy Closures with multiple Threads. The code ran faster on my dual-core machine than with single Thread.
The codes of this project is yet preliminary. It has a lot more to develop. Especially, it does not consier failure handling seriously.