17
Selenium Load Tests With Cicada Distributed
Source code available at https://github.com/cicadatesting/cicada-distributed-demos/tree/main/selenium-demo
First, generate the base Dockerfile and test.py:
cicada-distributed init
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"]
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()
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()
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
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
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!
17