I created a xunit
project and added specflow
with Gherkin
and selenium web drivers
to the project. I've following StepDefinition
file,
[Binding]
public class MyPageStepDefinition
{
private readonly UserContext _userContext;
private readonly ConfigurationDriver cd;
public MyPageStepDefinition(UserContext userContext)
{
_userContext = userContext;
cd = new ConfigurationDriver();
}
// Many Given, when and Then
}
I've UserContext
file as follows,
public class UserContext
{
public string email { get; set; }
}
I'm using IObjectContainer
to get help with ContextInjection in specflow as follows,
[Binding]
public class BrowserDriver
{
private readonly IObjectContainer _objectContainer;
// BrowserType is enum
public Dictionary<BrowserType, IWebDriver> _drivers;
public BrowserDriver(IObjectContainer objectContainer) {
_objectContainer = objectContainer;
_drivers = new Dictionary<BrowserType, IWebDriver>();
}
[BeforeScenario]
public void BeforeScenario()
{
_objectContainer.RegisterInstanceAs(_drivers);
}
}
My browser initialization code,
public IWebDriver InitBrowser(BrowserType browser)
{
IWebDriver driver = null;
switch (browser)
{
case BrowserType.Chrome:
ChromeOptions chromeOptions = new ChromeOptions();
if (!Debugger.IsAttached)
{
chromeOptions.AddArgument("headless");
chromeOptions.AddArguments("disable-gpu");
chromeOptions.AddArguments("window-size=1900,1280");
chromeOptions.AddArguments("--no-sandbox");
chromeOptions.AddArguments("--ignore-certificate-errors");
chromeOptions.AddArguments("--disable-dev-shm-usage");
}
driver = new ChromeDriver(chromeOptions);
break;
}
driver.Manage().Window.Maximize();
//driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(10);
return driver;
}
I call above method as follows,
SupportedBrowserList().ForEach(b => _drivers.Add(b, _testContext.InitBrowser(b)));
public List<BrowserType> SupportedBrowserList()
{
return new List<BrowserType>
{
BrowserType.Chrome,
};
}
and I use _drivers
as follows,
GetCurrentDriverList(_drivers).ForEach(d =>
{
// Do something on webpage, like d.FindElement(..);
});
public List<IWebDriver> GetCurrentDriverList(Dictionary<BrowserType, IWebDriver> drivers)
{
return new List<IWebDriver>(drivers.Values);
}
I've 2 features files to handle 2 flows. Most of the steps are common so they both call MyPageStepDefinition
constructor. When I run the feature files parallelly (default behavior of xunit) then one or the other test case fail, saying the email is not matching. I was able to debug and understand, that the email of one test is going in another. Looks like there is some race condition in Context Injection in specflow in parallel execution.
To validate my hypothesis, I made the test run sequentially using xunit.runner.json
file with following configuration,
{
"parallelizeTestCollections": false
}
and the code worked flawlessly. Now, if I run again in parallel it fails. It confirmed my hypothesis that specflow+xunit in parallel run is causing some issues. I'm pretty sure someone must have faced similar issue and fixed it, but I can't seem to figure it out. Can someone please help me in this? And How can I fix this?
Note: I've made the file simple, the UserContext
has more data fields. None of the fields are static
in UserContext
.