Grumbunks
Grumbunks

Reputation: 1257

Reusing the same webdriver for different tests, but not instantiating it every time

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...)

Upvotes: 0

Views: 436

Answers (1)

Boris
Boris

Reputation: 24443

Move your switch logic in a static initialization block, so that it is only executed once when the BasicTest class is loaded

static {
    ...
}

Upvotes: 2

Related Questions