.NET Testing Guide

This guide helps contributors write tests in the Selenium .NET codebase.

Test Framework

  • Tests use NUnit.
  • All tests inherit from DriverTestFixture.
  • Test HTML pages accessed via properties like simpleTestPage, javascriptPage.
  • WaitFor<T>() provides waiting with 5-second default timeout.
[TestFixture]
public class MyFeatureTest : DriverTestFixture
{
    [Test]
    public void ShouldFindElement()
    {
        driver.Url = simpleTestPage;
        IWebElement element = driver.FindElement(By.Id("foo"));
        Assert.That(element.Text, Is.EqualTo("expected"));
    }

    [Test]
    [IgnoreBrowser(Browser.Safari, "Safari doesn't support this")]
    public void ShouldDoSomething()
    {
        // Skipped on Safari
    }
}

Running Tests

Tests live in //dotnet/test/webdriver. The suite compiles once into a single binary; Bazel then generates a target per test class, plus a per-browser variant for each supported browser. The bare class target runs on the default browser (Firefox, the first entry in the browsers list in BUILD.bazel). Always use --pin_browsers.

bazel test //dotnet/test/webdriver/... --pin_browsers=true            # All tests, all browsers
bazel test //dotnet/test/webdriver:ElementFindingTests --pin_browsers=true        # One class, default browser
bazel test //dotnet/test/webdriver:ElementFindingTests-chrome --pin_browsers=true # One class on Chrome
bazel test //dotnet/test/webdriver:ElementFindingTests-edge --pin_browsers=true   # One class on Edge

# Additional Arguments
bazel test //dotnet/test/webdriver/... --flaky_test_attempts=3 --pin_browsers=true
bazel test //dotnet/test/webdriver/... --test_output=all --pin_browsers=true

To avoid passing --pin_browsers=true on every invocation, set it once in .bazelrc.local:

build --//common:pin_browsers

Running Tests in an IDE

Bazel is the source of truth for CI and release verification, but for day-to-day inner-loop development you can open dotnet/Selenium.slnx in Rider or Visual Studio and run tests through the built-in NUnit runner. This gives the same results as Bazel, modulo any build differences between bazel build and dotnet build, so it is worth confirming a change with bazel test before pushing.

Skipping Tests

Skips use NUnit attributes. Browser values: Browser.Chrome, Browser.Firefox, Browser.Edge, Browser.Safari, Browser.IE, Browser.Remote, Browser.All.

AttributeWhen to Use
[IgnoreBrowser(Browser.X, "reason")]Skip test for specific browser
[IgnorePlatform("windows", "reason")]Skip test on specific OS
[IgnoreTarget("net48", "reason")]Skip test on a specific .NET target framework
[Ignore("reason")]Skip test entirely (NUnit built-in)
[Test]
[IgnoreBrowser(Browser.Safari, "Safari doesn't support multiple instances")]
[IgnoreBrowser(Browser.IE, "IE is flaky")]
public void TestWithMultipleDrivers()
{
}

[Test]
[IgnorePlatform("windows", "Thread time not supported")]
public void TestLinuxOnly()
{
}

Driver Lifecycle

AttributeWhen to Use
[NeedsFreshDriver(IsCreatedBeforeTest = true)]Fresh driver before test
[NeedsFreshDriver(IsCreatedAfterTest = true)]Fresh driver after test
[Test]
[NeedsFreshDriver(IsCreatedBeforeTest = true, IsCreatedAfterTest = true)]
[IgnoreBrowser(Browser.Safari, "Safari doesn't support multiple instances")]
public void TestRequiringFreshDriver()
{
    IWebDriver driver2 = EnvironmentManager.Instance.CreateDriverInstance();
    try
    {
        // Test with multiple drivers
    }
    finally
    {
        driver2.Quit();
    }
}

Helpers

From DriverTestFixture:

MemberDescription
driverCurrent WebDriver instance
simpleTestPage, javascriptPage, etc.Test page URLs
WaitFor<T>(condition, timeout)Wait for condition (default 5s)
CreateFreshDriver()Create new driver instance

From EnvironmentManager.Instance:

MemberDescription
CreateDriverInstance()Create additional driver
CreateDriverInstance(options)Create driver with custom options
BrowserCurrent browser enum value

Test Organization

dotnet/test/
├── webdriver/                      # WebDriver tests
│   ├── DriverTestFixture.cs        # Base class
│   ├── *Tests.cs                   # Test files
│   └── Infrastructure/             # Custom attributes and test environment
│       ├── IgnoreBrowserAttribute.cs
│       ├── NeedsFreshDriverAttribute.cs
│       └── Environment/            # EnvironmentManager, DriverFactory
├── remote/                         # Remote/Grid tests
└── support/                        # Support library tests

Build Files

  • Adding tests shouldn't require Bazel changes—the suite globs **/*.cs.
  • Make sure new *Tests.cs files are under dotnet/test/webdriver, which has the dotnet_nunit_test_suite declaration in BUILD.bazel.