Grumbunks
Grumbunks

Reputation: 1257

Executing multiple JUnit tests using the same WebDriver object

I currently have a number of web UI tests which share different tests (for instance, the AccessOwnProfiletest and the AccessAdminMenu test both derive from the Logintest.) So when I run the two separately in my suite, a new instance of WebDriver will be created for both tests, so the Login test will be ran multiple times, because AccessOwnProfileand AccessAdminMenu both extend Login test, like so:

public class AccessOwnProfile extends Login {
    @Before
    public void setUp() throws Exception {
        super.setUp();
    }

    @After
    public void tearDown() throws Exception {
        super.tearDown();
    }

    @Test
    public void test() throws Exception {
        super.test();
        ...
    }

This is not good because if AccessOwnProfile and AccessAdminMenu are both used in my TestSuite, Login will be executed twice which is pointless. Ideally, I'd like to be able to only have to run the Login test once.

This isn't necessarily difficult, I only need to remove the extends in my test classes so every test is truly isolated. However every test still expects to pick up where the previous one left off. So I need to be able to keep the same instance of WebDriver for my entire TestSuite.

Basically what I want to do is to be able to run multiple JUnit tests that pick up from where the other left off, on the same browser instance. Basically, after a test, I wouldn't close the web browser and open a new one for the new test as I do right now. I'd just reuse the browser that's already opened. I'm not entirely sure how to do this and where this would be configured. I cannot pass a webdriver instance to my test classes in my TestSuite.

From my previous tests, it appears to me that each new instance of WebDriver keeps the same session from the previous one, meaning I could easily close the browser after every test and open it again for following tests. However I don't know if this is a reasonable expectation. It also means I can't just pick back up easily from the previous test's ending page, which is a bit of a problem. The only way I can think of how I would do this would be to write the current page URL into a temp file on tearDown(), and then, on the following test's setUp(), open that file and access the saved URL.

There has to be a better way.

EDIT: To clarify:

As it stands, I have divided different tests into multiple smaller tests so I can reuse code.

Imagine a EditAvatar test. You need to login and access your profile first.

Imagine a EditUsername test. You need to do that as well.

Instead of repeating those tasks which can be tests in and of themselves, I made them separate tests that these two tests inherit from.

The way i put it in place is that:

and so on

That means in my Test Suite, if I run EditUsername and EditAvatar:

To save on time I'd like to be able to use just one instance of the browser for the entire suite. That way I don't have to Login all over again for every test that requires access to a user panel for instance, because all I'll have to do is run my Login test once, and then I'm logged in for the rest of my TestSuite, I don't have to worry about repeating that particular task for each test.

Upvotes: 1

Views: 731

Answers (1)

bchmnnjcb
bchmnnjcb

Reputation: 86

I faced the exact same problem as you. Closing and reopening the WebDriver for every test was a no-go for me. So I digged the internet and I found a solution by Tarun Lalwani (Scroll down to Attempt 3 for the solution).

He basically found a way to reuse the WebDriver by extracting its drivers (e.g. GeckoDriver, ...) URL and SessionID which than can be used to create a new instance of a RemoteWebDriver that communicates with the same previous driver.

In addition, if you are using ChromeDriver this said solution might not work because Chrome is not using W3C Codec (as user2590117 stated) like the RemoteWebDriver in the above solution. So just follow the fix of user2590117 and you should be good to go.

To pass the drivers URL and SessionID between tests, I serialized both using jackson with some custom JsonSerializer objects, which worked just fine and which I unfortunately can't share because I did it for work.

Upvotes: 1

Related Questions