0

For true parallel execution of Selenium tests in NUnit, does the setup of the webdriver object need to be within the test method itself? Or is there a better way?

Previously, for parallel execution at the fixture level, I was able to create single objects (per fixture) within the [Setup] and backend methods. However, when moving towards test & fixture parallelism, I began encountering problems where tests within one fixture were all trying to access the same driver object.

I did manage to get a solution which involved [ThreadStatic] against the static driver object but this resulted in every test run keeping its driver object open till all had finished, which just seemed wrong.

I'm keen to push driver setup out of the tests and back toward [Setup] and backend methods, to reduce code duplication and keep the test method focussed on the test. I've researched the area but only seemed to come across fixture-level parallel execution but am keen for the full-on test & fixture-level parallel execution so I welcome any suggestions!

1
  • I've decided to go for fixture-level parallelism - this seems more in-line with how NUnit currently operates given I found a few NUnit github issues about parallel execution at the child level.
    – Moorpheus
    Mar 5, 2020 at 17:25

2 Answers 2

0

I have encountered this exact issue that you are facing and from my observations I can suggest 3 possible solutions:

1. ThreadStatic driver - it's the simplest way to have a unique driver instance per TestMethod. The actual value of the driver is linked to the thread your test is running on. Just remember to use [TearDown] to close the driver instance after the test is finished.

NOTE: Each [TestMethod] inside of a [TestFixture] has its own TestContext and runs on it's own thread when using parallelization. This context is created during the [SetUp] method and persists until [TearDown].

2. Multiple classes in the same file - you can place multiple classes marked as [TestFixture] in the same file and under the same Namespace. They can extend a base test class and have their own unique driver. The drawback is that you will have to manage each classes' driver individually.

3. Instantiate your driver inside of your Page Objects - this solution involves having one PageObject class (if you are familiar with the Page-Object pattern) which initializes your driver and then injects it into other PageObject classes.

For example: say you have a HomePage class. This class has a Driver property and when you invoke something like HomePage.GoTo() or .OpenBrowser() this Driver property gets a value assigned, depending on your configurations or any parameters you may want to give the method. Then when you navigate from your HomePage to another page, say "SettingsPage" you can have a method called HomePage.GoToSettingsPage() which returns a new SettingsPage(myDriver) and passes it your driver through the constructor. Of course, this will limit your ability to create new PageObjects at any point in your test other than the first one. Every time you navigate from one PageObject to another you will need to pass the driver. The main idea is to uncouple your driver instance from the test class.

There might be other ways, but I hope my suggestions helped.

0

Speaking from MSTest framework experience here, but why not have a base class for all test classes that has a [SetUp]. This will be automatically called for every test, so your driver creation code is in one place while every test will create its own driver object.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.