BDisp 1bd5e3761a Fixes #4391. Weird situation where ForceDriver with args doesn't persists on open scenario (#4395) 3 nedēļas atpakaļ
..
Application 1bd5e3761a Fixes #4391. Weird situation where ForceDriver with args doesn't persists on open scenario (#4395) 3 nedēļas atpakaļ
Configuration a6258ed398 Updates `IListDataSource.Render` to rename the `start` parameter to `viewportXOffset` (#4392) 3 nedēļas atpakaļ
Drawing c5906c2dc1 #4329—Major Terminal.Gui v2 Architecture Modernization: Application Decoupling, Terminology Improvements, and Nullable Migration (#4338) 3 nedēļas atpakaļ
Drivers 1bd5e3761a Fixes #4391. Weird situation where ForceDriver with args doesn't persists on open scenario (#4395) 3 nedēļas atpakaļ
FileServices fdeaa8331b Fixes #4298 - Updates test namespaces (#4299) 1 mēnesi atpakaļ
Input d53fcd7485 Fixes #4374 - Nukes all (?) legacy Driver and Application stuff; revamps tests (#4376) 1 mēnesi atpakaļ
Resources d53fcd7485 Fixes #4374 - Nukes all (?) legacy Driver and Application stuff; revamps tests (#4376) 1 mēnesi atpakaļ
Text 1bd5e3761a Fixes #4391. Weird situation where ForceDriver with args doesn't persists on open scenario (#4395) 3 nedēļas atpakaļ
View 1bd5e3761a Fixes #4391. Weird situation where ForceDriver with args doesn't persists on open scenario (#4395) 3 nedēļas atpakaļ
Views 1bd5e3761a Fixes #4391. Weird situation where ForceDriver with args doesn't persists on open scenario (#4395) 3 nedēļas atpakaļ
AssemblyInfo.cs cab22566ea Fixes #4107 - Revamps Terminal.Gui's `namespace` (#4109) 6 mēneši atpakaļ
LocalPackagesTests.cs fdeaa8331b Fixes #4298 - Updates test namespaces (#4299) 1 mēnesi atpakaļ
README.md 041e9de70e Migrate 210 tests to UnitTests.Parallelizable, add CreateFakeDriver helper, prove View.Draw() works in parallel tests, and provide comprehensive performance analysis (#4297) 1 mēnesi atpakaļ
TestSetup.cs 1bd5e3761a Fixes #4391. Weird situation where ForceDriver with args doesn't persists on open scenario (#4395) 3 nedēļas atpakaļ
UnitTests.Parallelizable.csproj a6258ed398 Updates `IListDataSource.Render` to rename the `start` parameter to `viewportXOffset` (#4392) 3 nedēļas atpakaļ
UnitTests.Parallelizable.csproj.DotSettings b0f32811eb Fixes #3930 - Splits tests to `Tests/UnitTests`, `Tests/IntegrationTests`, `Tests/StressTests` (#3954) 9 mēneši atpakaļ
runsettings.coverage.xml d53fcd7485 Fixes #4374 - Nukes all (?) legacy Driver and Application stuff; revamps tests (#4376) 1 mēnesi atpakaļ
runsettings.xml d53fcd7485 Fixes #4374 - Nukes all (?) legacy Driver and Application stuff; revamps tests (#4376) 1 mēnesi atpakaļ
xunit.runner.json b0f32811eb Fixes #3930 - Splits tests to `Tests/UnitTests`, `Tests/IntegrationTests`, `Tests/StressTests` (#3954) 9 mēneši atpakaļ

README.md

UnitTests.Parallelizable

This project contains unit tests that can run in parallel without interference. Tests here must not depend on global state or static Application infrastructure.

Migration Rules

Tests CAN be parallelized if they:

  • ✅ Test properties, constructors, and basic operations
  • ✅ Use [SetupFakeDriver] without Application statics
  • ✅ Call View.Draw(), LayoutAndDraw() without Application statics
  • ✅ Verify visual output with DriverAssert (when using [SetupFakeDriver])
  • ✅ Create View hierarchies without Application.Top
  • ✅ Test events and behavior without global state
  • ✅ Use View.BeginInit() / View.EndInit() for initialization

Tests CANNOT be parallelized if they:

  • ❌ Use [AutoInitShutdown] - requires Application.Init/Shutdown which creates global state
  • ❌ Set Application.Driver (global singleton)
  • ❌ Call Application.Init(), Application.Run/Run<T>(), or Application.Begin()
  • ❌ Modify ConfigurationManager global state (Enable/Load/Apply/Disable)
  • ❌ Access ConfigurationManager including ThemeManager and SchemeManager - these rely on global state
  • ❌ Access SchemeManager.GetSchemes() or dictionary lookups like schemes["Base"] - requires module initialization
  • ❌ Access View.Schemes - there can be weird interactions with xunit and dotnet module initialization such that tests run before module initialization sets up the Schemes array
  • ❌ Modify static properties like Key.Separator, CultureInfo.CurrentCulture, etc.
  • ❌ Set static members on View subclasses (e.g., configuration properties like Dialog.DefaultButtonAlignment) or any static fields/properties - these are shared across all parallel tests
  • ❌ Use Application.Top, Application.Driver, Application.MainLoop, or Application.Navigation
  • ❌ Are true integration tests that test multiple components working together

Important Notes

  • Many tests in UnitTests blindly use the above patterns when they don't actually need them
  • These tests CAN be rewritten to remove unnecessary dependencies and migrated here
  • Many tests APPEAR to be integration tests but are just poorly written and cover multiple surface areas - these can be split into focused unit tests
  • When in doubt, analyze if the test truly needs global state or can be refactored

How to Migrate Tests

  1. Identify tests in UnitTests that don't actually need Application statics
  2. Rewrite tests to remove [AutoInitShutdown], Application.Begin(), etc. if not needed
  3. Move the test to the equivalent file in UnitTests.Parallelizable
  4. Delete the old test from UnitTests to avoid duplicates
  5. Verify no duplicate test names exist (CI will check this)
  6. Test to ensure the migrated test passes

Example Migrations

Simple Property Test (no changes needed)

// Before (in UnitTests)
[Fact]
public void Constructor_Sets_Defaults ()
{
    var view = new Button ();
    Assert.Empty (view.Text);
}

// After (in UnitTests.Parallelizable) - just move it!
[Fact]
public void Constructor_Sets_Defaults ()
{
    var view = new Button ();
    Assert.Empty (view.Text);
}

Remove Unnecessary [SetupFakeDriver]

// Before (in UnitTests)
[Fact]
[SetupFakeDriver]
public void Event_Fires_When_Property_Changes ()
{
    var view = new Button ();
    var fired = false;
    view.TextChanged += (s, e) => fired = true;
    view.Text = "Hello";
    Assert.True (fired);
}

// After (in UnitTests.Parallelizable) - remove attribute!
[Fact]
public void Event_Fires_When_Property_Changes ()
{
    var view = new Button ();
    var fired = false;
    view.TextChanged += (s, e) => fired = true;
    view.Text = "Hello";
    Assert.True (fired);
}

Replace Application.Begin with View Initialization

// Before (in UnitTests)
[Fact]
[AutoInitShutdown]
public void Focus_Test ()
{
    var view = new Button ();
    var top = new Toplevel ();
    top.Add (view);
    Application.Begin (top);
    view.SetFocus ();
    Assert.True (view.HasFocus);
    top.Dispose ();
}

// After (in UnitTests.Parallelizable) - use BeginInit/EndInit!
[Fact]
public void Focus_Test ()
{
    var superView = new View ();
    var view = new Button ();
    superView.Add (view);
    superView.BeginInit ();
    superView.EndInit ();
    view.SetFocus ();
    Assert.True (view.HasFocus);
}

Running Tests

Tests in this project run in parallel automatically. To run them:

dotnet test Tests/UnitTestsParallelizable/UnitTests.Parallelizable.csproj

See Also