Terminal.Gui provides testing infrastructure through two complementary driver implementations:
FakeDriver extends the abstract ConsoleDriver base class and is designed for:
AutoInitShutdownAttribute in traditional unit tests[Fact]
[AutoInitShutdown] // Automatically initializes and shuts down Application
public void My_Test()
{
// Application is already initialized with FakeDriver
Assert.NotNull(Application.Driver);
Assert.True(Application.Initialized);
}
[Fact]
[AutoInitShutdown]
public void Test_Resize_Behavior()
{
// Start with default size (80x25)
Assert.Equal(80, Application.Driver.Cols);
Assert.Equal(25, Application.Driver.Rows);
// Simulate a terminal resize
AutoInitShutdownAttribute.FakeResize(new Size(120, 40));
// Verify the resize took effect
Assert.Equal(120, Application.Driver.Cols);
Assert.Equal(40, Application.Driver.Rows);
Assert.Equal(new Rectangle(0, 0, 120, 40), Application.Screen);
}
[Fact]
[AutoInitShutdown]
public void Test_Resize_Events()
{
bool eventFired = false;
Size? newSize = null;
Application.Driver.SizeChanged += (sender, args) =>
{
eventFired = true;
newSize = args.Size;
};
AutoInitShutdownAttribute.FakeResize(new Size(100, 30));
Assert.True(eventFired);
Assert.Equal(100, newSize.Value.Width);
Assert.Equal(30, newSize.Value.Height);
}
[Fact]
[AutoInitShutdown]
public void Test_Keyboard_Input()
{
// Queue keyboard input before it's processed
FakeConsole.PushMockKeyPress(new ConsoleKeyInfo('a', ConsoleKey.A, false, false, false));
FakeConsole.PushMockKeyPress(new ConsoleKeyInfo('\r', ConsoleKey.Enter, false, false, false));
// Your test logic that processes the input
// ...
}
[Fact]
[AutoInitShutdown]
public void Test_Screen_Output()
{
Application.Top = new Toplevel();
var label = new Label { Text = "Hello", X = 0, Y = 0 };
Application.Top.Add(label);
Application.Begin(Application.Top);
AutoInitShutdownAttribute.RunIteration();
// Access driver contents to verify output
var contents = Application.Driver.Contents;
Assert.NotNull(contents);
// Verify specific characters were drawn
// contents[row, col] gives you access to individual cells
}
Understanding the relationship between key driver properties:
Rectangle representing the full console area. Always starts at (0,0) with size (Cols, Rows).[rows, cols] containing the actual screen buffer cells.When you resize:
SetBufferSize(width, height) or FakeResize(Size) is calledCols and Rows are updatedContents buffer is reallocated to match new dimensionsScreen property returns updated rectangleSizeChanged event fires with new size⚠️ Important: FakeDriver is not thread-safe. Tests that use FakeDriver should:
AutoInitShutdownAttribute to ensure clean initialization/shutdown per testFor parallel-safe tests, use the UnitTestsParallelizable project with its own test infrastructure.
FakeDriver differs from production drivers (WindowsDriver, UnixDriver, DotNetDriver) in several ways:
| Aspect | FakeDriver | Production Drivers |
|---|---|---|
| Screen Size | Programmatically set via SetBufferSize |
Determined by actual terminal size |
| Input | Queued via FakeConsole.PushMockKeyPress |
Reads from actual stdin |
| Output | Captured in memory buffer | Written to actual terminal |
| Resize | Triggered by test code | Triggered by OS (SIGWINCH, WINDOW_BUFFER_SIZE_EVENT) |
| Buffer vs Window | Always equal (no scrollback) | Can differ (scrollback support) |
For tests that need more control, you can access the driver directly:
[Fact]
public void Test_With_Direct_Driver_Access()
{
// Create and initialize driver manually
Application.ResetState(true);
var driver = new FakeDriver();
Application.Driver = driver;
Application.SubscribeDriverEvents();
// Use driver directly
driver.SetBufferSize(100, 50);
Assert.Equal(100, driver.Cols);
Assert.Equal(50, driver.Rows);
// Cleanup
Application.ResetState(true);
}
For new test infrastructure, consider using the modern component factory approach via FakeComponentFactory:
var factory = new FakeComponentFactory();
// Modern driver initialization through component factory pattern
// This is used internally by the fluent testing infrastructure
The fluent testing project (TerminalGuiFluentTesting) provides a higher-level API built on this architecture.