DEV Community

Jeremy Herzog
Jeremy Herzog

Posted on

Selenium Load Tests With Cicada Distributed

Cicada Distributed is unique because it allows end-to-end browser tests and load tests with many users to be run with the same framework. This is particularly useful with server side rendered websites, where the site’s performance is more limited. In this tutorial, you’ll learn how to modify the Cicada Dockerfile with a Selenium installation, and run Selenium tests through CicadaD.

Source code available at https://github.com/cicadatesting/cicada-distributed-demos/tree/main/selenium-demo

Installing Selenium

First, generate the base Dockerfile and test.py:

cicada-distributed init
Enter fullscreen mode Exit fullscreen mode

Next, modify the Dockerfile in order to install Chrome, Webdriver, and Selenium for Python.

FROM cicadatesting/cicada-distributed-base-image:1.3.0

RUN apt-get update
RUN apt-get install -y bash unzip curl xvfb libxi6 libgconf-2-4 gnupg

# Install chrome
RUN curl -sS -o - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add
RUN echo "deb http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google-chrome.list
RUN apt-get -y update
RUN apt-get -y install google-chrome-stable

# Install ChromeDriver.
# NOTE: may have to change this to appropriate version of google-chrome-stable listed here: https://www.ubuntuupdates.org/pm/google-chrome-stable
RUN wget -N https://chromedriver.storage.googleapis.com/92.0.4515.107/chromedriver_linux64.zip -P ~/
RUN unzip ~/chromedriver_linux64.zip -d ~/
RUN rm ~/chromedriver_linux64.zip
RUN mv -f ~/chromedriver /usr/local/bin/chromedriver
RUN chown root:root /usr/local/bin/chromedriver
RUN chmod 0755 /usr/local/bin/chromedriver

# Install selenium
RUN pip install selenium

# Install tests
COPY . .

ENTRYPOINT ["python", "-u", "test.py"]
Enter fullscreen mode Exit fullscreen mode

Adding Selenium to the Test

In this example, we’ll add the Selenium driver to a custom user loop. You don’t have to do it this way, but it is a nice way of separating the driver setup code from the test code in Cicada.

First, create a custom user loop in test.py to initialize the driver:

from datetime import datetime
from typing import Any

from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from cicadad.core.scenario import UserCommands
from cicadad.core.decorators import scenario, user_loop, users_per_container
from cicadad.core.engine import Engine

CHROMEDRIVER_PATH = "/usr/local/bin/chromedriver"
WINDOW_SIZE = "1920,1080"

engine = Engine()


def chromedriver_user_loop(user_commands: UserCommands, context: dict):
    chrome_options = Options()

    chrome_options.add_argument("--headless")
    chrome_options.add_argument(f"--window-size={WINDOW_SIZE}")
    chrome_options.add_argument("--no-sandbox")

    driver = webdriver.Chrome(
        executable_path=CHROMEDRIVER_PATH, chrome_options=chrome_options
    )

    start = datetime.now()

    output, exception, logs = user_commands.run(
        context=context,
        driver=driver,
    )

    end = datetime.now()

    user_commands.report_result(
        output,
        exception,
        logs,
        time_taken=(end - start).seconds,
    )

    driver.close()
Enter fullscreen mode Exit fullscreen mode

Next, pass it to the test function:

@scenario(engine)
@user_loop(chromedriver_user_loop)
def get_tutorial(context, driver: Any):
    print(driver)


if __name__ == "__main__":
    engine.start()
Enter fullscreen mode Exit fullscreen mode

Creating a Selenium Test

The last step is to add test code to verify functionality of your site. Let’s add a simple test to the Cicada Docsite which verifies clicking the Tutorial navigation button will load the installation page:

@scenario(engine)
@user_loop(chromedriver_user_loop)
def get_tutorial(context, driver: Any):
    driver.get("https://cicadatesting.github.io/cicada-distributed-docs/")

    em = driver.find_element_by_link_text("Tutorial")

    assert em is not None
    em.click()

    url = driver.current_url

    assert "installation" in url, f"Did not navigate to tutorial; current url is {url}"
    return url
Enter fullscreen mode Exit fullscreen mode

In addition, limit the users_per_container parameter, introduced in version 1.3.0, to 1 in order to prevent resource contention in the user containers:

Finally, run the test:

cicada-distributed run
Enter fullscreen mode Exit fullscreen mode

The test should hit the docsite and return the URL of the installation page.

Congratulations! You’ve learned how to run Selenium through Cicada Distributed!

Top comments (0)