NUnit & lifecycle
Introduction
CSTesting for .NET (C:\CSTesting-DotNet) is meant to be used with NUnit. You structure tests with [TestFixture], [SetUp], [TearDown], [OneTimeSetUp], [OneTimeTearDown], and [Test] as usual. The CSTesting library adds CSTestingTestBase (a Browser property) and optionally CSTestingNUnitBrowserFixtureBase, which closes Playwright after each test and supports pause-on-failure. Nothing injects a browser automatically—you call CreateBrowserAsync yourself (see SampleRecordedTest.cs in the repo).
NUnit and CSTesting attributes
| Attribute | Role |
|---|---|
[TestFixture] | Marks a class that contains tests. |
[SetUp] | Runs before each [Test] — typical place to CreateBrowserAsync and assign Browser. |
[TearDown] | Runs after each test. If you use CSTestingNUnitBrowserFixtureBase, do not add a second tear-down that closes the browser (the base handles it). |
[Test] | Async test method; use await Browser!.GotoAsync(...), etc. |
[Test(Description = "...")] | Human-readable description in runners and reports. |
[CSTestingTag("smoke")] | Maps to NUnit category smoke for dotnet test --filter TestCategory=smoke (CSTestingTagAttribute.cs). |
[Category("smoke")] | Standard NUnit category; same filtering idea. |
Execution order
NUnit runs one-time setup/teardown for the fixture, then for each test: [SetUp] → [Test] → [TearDown]. Whether you share one browser across tests or create a new browser per test is your choice; the sample uses one browser per test via [SetUp] and closes it in the fixture base [TearDown].
Base classes
| Type | Description |
|---|---|
CSTestingTestBase | Exposes protected ICSTestingBrowser? Browser { get; set; }. You assign it after CreateBrowserAsync. |
CSTestingNUnitBrowserFixtureBase | Extends the above; adds [TearDown] that optionally pauses on failure (env vars) then await Browser.CloseAsync(). |
Headed browser:
Browser = await CreateBrowserAsync(new CSTestingOptions { Headless = false });
[Test] example
[Test]
public async Task Login_RedirectsToWelcome()
{
await Browser!.GotoAsync("https://example.com/login");
await Browser.TypeAsync("name=user", "alice");
await Browser.ClickAsync("button[type=submit]");
await Browser.WaitForURLAsync("**/welcome", 10_000);
}
[Test(Description = "Check example.com heading")]
public async Task Example_HasHeading()
{
await Browser!.GotoAsync("https://example.com");
var text = await Browser.Locator("h1").GetTextContentAsync();
Assert.That(text, Does.Contain("Example"));
}
Runner: dotnet test
There is no Java CSTestingRunner. Build and run tests with the .NET SDK:
cd C:\CSTesting-DotNet
dotnet build
dotnet test
Tag filter (see README.md):
dotnet test --filter "TestCategory=smoke"
Full example (matches repo sample)
using System.Threading.Tasks;
using CSTesting;
using CSTesting.NUnit;
using NUnit.Framework;
using static CSTesting.CSTesting;
namespace MyTests;
[TestFixture]
public class SampleTests : CSTestingNUnitBrowserFixtureBase
{
[SetUp]
public async Task SetUp()
{
if (Browser == null)
Browser = await CreateBrowserAsync(new CSTestingOptions { Headless = true });
}
[Test]
[CSTestingTag("smoke")]
public async Task ExampleDotCom()
{
await Browser!.GotoAsync("https://example.com");
var text = await Browser.Locator("h1").GetTextContentAsync();
Assert.That(text, Does.Contain("Example Domain"));
}
}
Run: dotnet test from the test project directory.
Without CSTestingNUnitBrowserFixtureBase
You can inherit only CSTestingTestBase and call await Browser!.CloseAsync() in your own [TearDown], or manage ICSTestingBrowser in a local variable with await using / try/finally.
Summary
| Topic | CSTesting .NET |
|---|---|
| Test method | [Test] async Task |
| Setup | [SetUp] → create browser, assign Browser |
| Teardown | Base fixture closes browser; or your own [TearDown] |
| Tags | [CSTestingTag("name")] or [Category("name")] |
| Assertions | NUnit Assert.That; not browser.assertThat |
| CLI | dotnet test |