Issue
I'm making a project that runs tests on a web application using Selenium Webdriver. I need to be able to test different browsers in my CI Pipeline, so when I execute a test suite, I specify what browser should be used.
mvn test -Dwebdriver.gecko.driver="/webdrivers/geckodriver" -Dwebdriver.chrome.driver="/webdrivers/chromedriver" -DbrowserUnderTest="headless-firefox"
The tests use a WebDriver
object to manipulate the browser, so, to make the code easy to maintain, I made it so that every test class inherits from a class called BasicTest
where the WebDriver driver
object is instantiated.
Also, to make test execution faster, I made it so that tests reuse the same instance of the browser, so, when a test ends, the next test uses the already-opened browser. That is why in the code of BasicTest
, my WebDriver
objects are defined as public static
:
public static FirefoxOptions ff_opt_headless = new FirefoxOptions().setHeadless(true);
public static ChromeOptions chrome_opt_headless = new ChromeOptions().addArguments("--headless");
public static WebDriver firefox_driver_headless = new FirefoxDriver(ff_opt_headless);
public static WebDriver chrome_driver_headless = new ChromeDriver(chrome_opt_headless);
public static WebDriver driver;
public BasicTest() throws Exception {
String browserUnderTest = System.getProperty("browserUnderTest");
switch (browserUnderTest) {
case "headless-firefox":
driver = firefox_driver_headless;
break;
case "headless-chrome":
driver = chrome_driver_headless;
break;
}
}
The problem that I have here is that firefox_driver_headless
and chrome_driver_headless
are instantiated every time, meaning that even if I specify Firefox for a test suite Chrome will also be opened uselessly. So I need to find a way to not instantiate the firefox_driver_headless
and chrome_driver_headless
objects when BasicTest
is created.
If I keep it that way, when I add drivers for browsers that may not be available on every platform my tests can be run on, I will encounter issues. (ex: if my tests run on Linux, and I try to instantiate an internet_explorer_webdriver
object, it will fail.)
I already tried to instantiate them in the switch case like below:
public static WebDriver driver;
switch (browserUnderTest) {
case "headless-firefox":
WebDriver firefox_driver_headless = new FirefoxDriver(ff_opt_headless);
driver = firefox_driver_headless;
break;
case "headless-chrome":
WebDriver chrome_driver_headless = new ChromeDriver(chrome_opt_headless);
driver = chrome_driver_headless;
break;
}
While this does not open Chrome when I launch my test, it also reopens Firefox for each test, which is not what I want: I want the same instance of the browser to be reused for every test.
So what is the solution here? Should I just give up trying to make it so that the same instance of the browser is reused for every test? I intended for the TestSuite
would follow a logical order like a normal person navigating. (ie, to test a "change avatar" feature, the Login
test would be executed, then after that the AccessProfile
test would be executed, then after that ChangeAvatar
...)
Solution
Move your switch logic in a static initialization block, so that it is only executed once when the BasicTest
class is loaded
static {
...
}
Answered By - Boris
Answer Checked By - Dawn Plyler (JavaFixing Volunteer)