What is the best way to have a SpecFlow project run across multiple browsers?

I'm working on setting up a SpecFlow project to test a portal. Thus far I've haven't had issues writing some "hello world" features and steps. My question is as the testing project grows, what is the best way to have the features run against a set of browsers?

Here are some solutions I've been able to come up with or see examples of online:

• The browsers can be passed in as Examples for each Scenerio (Source), but this seems like it would bloat the Scenerio.

• I looked into Tags and BeforeScenerio hooks, but that doesn't allow multiple browsers to be tested as the steps wouldn't be executed against each tag.

• Setting the driver set in a static helper and depending which you want to run, the code can be commented/uncommented (Source). I probably wouldn't have it be commented out code, but abstract it into some Setting/Factory class. It would still be a code change though.

• Following with the option above, the driver could be selected on a build variable (#if IETESTING, etc), but I thought I once came across some statements claiming that these could be considered anti-patterns.

My final thoughts would be that the feature/gherkin files should not change to test different browsers for the great majority of cases as most features shouldn't have a browser requirement (exceptions could be newer HTML5 APIs & their fallbacks). I believe if they were controlled by some configuration that could be applied after compiling would preferable, but I'm unclear how best to accomplish this.

Hello World

It appears that NUnit http://www.nunit.org/index.php?p=testFixture&r=2.5 now supports parameterized test fixtures. This may allow you to create a test that will do what you need. This SO answer has a similar question for NUnit selenium tests.

You might see if you modify your SpecFlowFeature1Steps.cs and run it to see what happens. Don't forget to reference the other browsers in the using.

[TestFixture(typeof(FirefoxDriver))]
[TestFixture(typeof(InternetExplorerDriver))]
public class TestWithMultipleBrowsers<TWebDriver> where TWebDriver : IWebDriver, new()
{
private IWebDriver driver;

[SetUp]
public void CreateDriver () {
this.driver = new TWebDriver();
}


I would be sure to ask yourself though if Specflow is the appropriate place for multi browser tests.

• This was my solution before Specflow, but since the actual NUnit TestFixture are generated by Specflow I haven't found a way to integrate this into the solution. – Paul DelRe Feb 26 '13 at 13:39
• I would be interested in some expansion on your final comment on the proper place for multi browser testing. – Paul DelRe Feb 26 '13 at 13:39
• I'm interested as to why people are upvoting this, because it doesn't appear to actually solve the problem as written - SpecFlow generates the TestFixtures and it's not obvious how to go from here to multiple browsers on a given scenario. Is there a way to get to a solution here that I can't see? – Ben Oct 13 '14 at 10:08
• Guessing at my 20-month-ago-self, because it was a good answer (well thought out and written with research) but not a solution (and isn't marked as such). – Paul DelRe Oct 14 '14 at 14:21

One way we solved this was to have a Given step at the start of each of our features

Given I am using <browser>
And I am on the Homepage
And I click on the Logon Link
Then I am taken to the Logon Page

Examples:
|browser|
|Chrome|
|Firefox|
|etc|


I then have a Before and After Scenario which configures each of my Browsers and completes the cleanup

[BeforeScenario]
public void ConfigureChrome()
{
var chromeDriver = new ChromeDriver();

// Configure here
//ConfigureDriver(chromeDriver);
chromeDriver.Manage().Window.Position = new System.Drawing.Point(2192, -963);
chromeDriver.Manage().Window.Maximize();

var chromeDriverWait = new WebDriverWait(chromeDriver, TimeSpan.FromSeconds(20));

ScenarioContext.Current[WebDriverType.Chrome.ToString()] = chromeDriver;
ScenarioContext.Current[$"{WebDriverType.Chrome.ToString()}-Wait"] = chromeDriverWait; } [AfterScenario] public void CleanUpChrome() { var driver = (IWebDriver) ScenarioContext.Current[WebDriverType.Chrome.ToString()]; driver.Quit(); } [BeforeScenario] public void ConfigureFirefox() { var firefoxDriver = new FirefoxDriver(); // Configure here //ConfigureDriver(firefoxDriver); ScenarioContext.Current[WebDriverType.Firefox.ToString()] = firefoxDriver; } [AfterScenario] public void CleanUpFirefox() { var driver = (IWebDriver)ScenarioContext.Current[WebDriverType.Firefox.ToString()]; driver.Quit(); }  And then my Given Step is defined [Given(@"I am using (.*)")] public void GivenIAmUsingBrowser( string browser) { WebDriverType driverType; if (!Enum.TryParse(browser, out driverType)) throw new InvalidOperationException("Invalid driver"); ScenarioContext.Current.Add("driver", ScenarioContext.Current[browser.ToString()]); ScenarioContext.Current.Add("driverWait", ScenarioContext.Current[$"{browser.ToString()}-Wait"]);
}


While this is not ideal and I am working on seeing if there are alternative ways of solving this issue it is a workaround that we have managed to get to work.

I struggled with this and what I ended up doing at the moment was generating different tests for different browsers, as much as I wanted repeatability I did not see this as doable within the current framework and browser functionality. The largest problem you will find with cross-browser support is going to be where you have to deal with buttons, click and keys.enter do not work consistently across IE, Chrome or Firefox. Finding page elements will also be different as CSS is handled differently across the browsers as well.

I have looked occasionally for an option you have noted but I personally find that the exceptions I would need to make for functionality as well as browser types would make my test code too bloated so I use SpecFlow to limit my steps and break off to different sections for the browser specific handling when necessary. To me that manages the duplication I need to do and still gets me effective testing.