There is no "best" way of doing this, however the way I accomplished this is below:
I created an Enum:
/// <summary>
/// Enum that holds references to different browsers used in testing.
/// </summary>
public enum BrowserTypeEnum
{
/// <summary>
/// Google Chrome.
/// </summary>
Chrome,
/// <summary>
/// Mozilla Firefox.
/// </summary>
Firefox,
/// <summary>
/// Internet Explorer.
/// </summary>
InternetExplorer
}
Called it in the TestFixture like so:
/// <summary>
/// Tests related to browsing Google
/// </summary>
[TestFixture(BrowserTypeEnum.Chrome)]
[TestFixture(BrowserTypeEnum.Firefox)]
public class GoogleTests : AbstractTestFixture
{
}
In AbstractTestFixture:
/// <summary>
/// Create's the browser used for this test fixture.
/// <para>
/// Must always be called as part of the test fixture set up.
/// </para>
/// <para>
/// It is the actual test fixture's responsibility to launch the browser. (Usually in the test fixture setup)
/// </para>
/// </summary>
protected override void CreateBrowser()
{
switch (BrowserType)
{
case BrowserTypeEnum.Chrome:
Browser = new ChromeDriver();
break;
case BrowserTypeEnum.Firefox:
Browser = new FirefoxDriver();
break;
case BrowserTypeEnum.InternetExplorer:
Browser = new IEDriver();
break;
default:
break;
}
}
May not be the best solution, but I found it pretty readable. The alternative is using something like Selenium Grid, or maybe passing the type of driver into NUnit and create it directly. You've already tried this (passing the direct type of driver) and it doesn't seem to be what you are after. The only difference could be that you pass in the type of driver into the test fixture, not the actual test.
Another alternative is if you use a CI Server solution, create a configuration setting to indicate which browser to use for the test. Have the CI Driver repeat the tests three times, editing that configuration setting each time.
I do agree, it is not the actual tests responsibility to know what kind of driver they are working with, this is why I pushed that responsibility upwards into the test fixture. The way I am doing it may not be the most "elegant" way, but it is the most readable for me at least. Somebody looking at my code can easily see that this test fixture is getting repeated, and what browsers are repeating the steps.
For me, the creation of the driver must always be in the actual TestFixture (not a base test fixture). The reason is because there is a bit of logic I want to do before opening the browser - if this logic fails (in a Setup or TestFixtureSetup method), then NUnit won't run any teardown methods. So a browser window will be left open.
So to remedy this, the very last thing I do in TestFixtureSetup, before the test is ran, is called "CreateBrowser".