Selenium Load Testing Alternative: Flood Element

The ability to use your existing Selenium functional scripts as load tests seems like a silver bullet. Many companies have vast functional automation suites built using Selenium, so the prospect of Selenium load testing is enticing.

Reasons for Selenium Load Testing

If you are new to load testing, It’s very easy to want to run ALL your functional tests as load tests. However it is recommended to only choose a subset of these functional test cases to be used for load testing, as these tests can be much more expensive to run.  Generally these should be chosen with the following characteristics:

  1. User flows that are critical for your business.
  2. User flows that are executed frequently.
  3. Business transactions  that are executed in large volumes.
  4. Technical processes that may have high impact on system resources.

Limitation of Selenium Load Testing

The issue with using Selenium load testing specifically is the amount of user concurrency for the server resources required. Selenium was never intended to be used as a load testing tool and has been developed to run for primarily functional testing with one user per instance.

Our Engineers here at Flood have optimized Selenium as much as possible and still those tests remain very expensive.  Our standard (m5.xlarge) load injection node instances can only support 5 concurrent users. This means that executing Selenium-based load tests with a large amount of users will require a significant number of nodes and subsequently be fairly expensive to run.

Introducing Flood Element as a Selenium Load Testing Alternative

Enter Flood Element – an alternative to Selenium that takes the concept of using full browsers like Selenium whil adding several benefits: :

  • Nearly identical syntax for referencing UI objects (by id, css, xpath etc.).
  • 10x more concurrency – with the ability to support up to 50 concurrent users per load injection node.
  • Built in test data support – with the ability to integrate CSV and also Faker.js data generation modules directly into the script.
  • Purpose built and tuned for browser level user load testing with advanced statistics.

How to Convert from Selenium Load Testing to Flood Element

Currently there isn’t an automated method available to directly translate a Selenium script to Flood Element. However most of the steps for referencing and using objects are identical when using Flood Element and can be translated across directly from your existing Selenium script.

Let’s take a look at a few common functions and their examples.

Measuring transactions.

Transactions which are important to measure for load tests are separated by the following statements in Selenium:

flood.start_transaction("User Registration");flood.passed_transaction(driver, “User Registration”);

In Flood Element we use ‘Steps’ to measure response times – and these can contain as many or as little statements as you wish just as using the start/passed transactions around your Selenium statements. They are denoted with the following syntax:

step('User Registration', async browser => {})

Page navigation.

The first step for both Selenium and Flood Element is usually to navigate to an initial URL so that subsequent UI object interactions can be made to complete the test case.

In Selenium we would have the following statement:

driver.get("https://flooded.io");

whereas in Flood Element we would use the following statement:

await browser.visit('https://flooded.io')

Text input field entry.

In Selenium we may want to fill in a username field by using the following statement:

driver.findElement(By.name("userName")).sendKeys("jason@flood.io");

The equivalent in Flood Element would be:

await browser.type(By.nameAttr('userName'), "jason@flood.io")

Interacting with buttons.

Clicking on a button object in Selenium is very similar to Flood Element too. In Selenium:

driver.findElement(By.xpath("//div[@id='btn-submit']")).click();

The equivalent in Flood Element?

await browser.findElement(By.xpath('//div[@id='btn-submit']')).click()

Select from a dropdown list box.

Selecting a value from a standard drop down object can be done quite easily. In Selenium:

new Select(driver.findElement(By.name("state"))).selectByVisibleText("Victoria");

Very similar, is doing this in Flood Element:

await browser.selectByValue('#state','Victoria')

Waiting for objects.

We may want to wait for a particular object to appear on the page before we interact with it. This is fairly common and through Selenium, you would use the following statement:

wait.until(ExpectedConditions.textToBePresentInElement(By.xpath("//div[@id='logout-header']"), "Are you sure you want to exit"));

In Flood Element:

let validation = By.visibleText('Are you sure you want to exit')await browser.wait(Until.elementIsVisible(validation))

Logging to the console.

We can log text for debugging and informational purposes to the console. This is often done to see what data is being used and perhaps even to help indicate what steps we have been able to execute within our script. In Selenium we would use:

System.out.println("radio button is selected");

In Flood Element:

console.log('radio button is selected')

Putting it all together.

We’ve just covered some of the most common Selenium statements and their equivalents in Flood Element. As you can see there is much similarity and the learning curve between the tools for general object definition and interactivity is very small.

In a lot of ways a Flood Element script structure is much simpler in that a lot of the libraries necessary to be imported into a Selenium script is already included by default in the main Flood Element library.

For example here’s a list of common libraries needing to be imported into your typical Selenium script:

import java.net.URL;
import java.util.concurrent.TimeUnit;
import java.util.List;
import java.util.Random;
import java.lang.String;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WebDriverException;
import java.util.regex.Pattern;
import java.util.concurrent.TimeUnit;
import org.junit.*;
import static org.junit.Assert.*;
import static org.hamcrest.CoreMatchers.*;
import org.openqa.selenium.*;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.remote.Augmenter;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.remote.SessionId;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.openqa.selenium.support.ui.Select;
import io.flood.selenium.FloodSump;

And here is what needs to be imported into a typical Flood Element script:

import { step, TestSettings, TestData, Until, By, Browser, MouseButtons, Device } from '@flood/element'
import * as assert from 'assert'

As you can see – Flood Element is built from the ground up to include a lot of what a load tester needs in terms of Test Data, Settings, assertions etc. right out of the box.

Go Forth and Test with Flood Element

For a more detailed conversion estimate for your specific Selenium scripts – please don’t hesitate to contact our friendly Support staff who can have a chat about how best to approach migrating onto Flood Element.


Ready to get started?

Sign up or request a demo today.