Repository navigation
Testing and Development Tools
Educational guide on available tools for testing, profiling, and accessibility
Avalonia provides headless testing that allows running UI tests without a visible GUI, perfect for CI/CD pipelines.
Official Documentation: Headless Testing | Avalonia Docs
Key Features:
- Runs on servers without X11/display
- Tests execute in same process as application
- Supports XUnit and NUnit
- Direct access to UI elements and state
Setup:
<PackageReference Include="Avalonia.Headless.XUnit" Version="11.2.5" />Usage:
[AvaloniaFact] // Instead of [Fact]
public async Task TestUIBehavior()
{
var vm = new MainWindowViewModel();
await Dispatcher.UIThread.InvokeAsync(async () =>
{
await vm.LoadDocumentAsync(testPath);
});
vm.DocumentName.Should().NotBeEmpty();
}Source: Headless Platform | Avalonia Docs
Avalonia.Headless provides methods to simulate user input:
// Create window
var window = new MainWindow { DataContext = vm };
// Simulate mouse drag
window.SimulatePointerDown(new Point(100, 100), MouseButton.Left);
window.SimulatePointerMove(new Point(200, 150));
window.SimulatePointerUp(new Point(200, 150));
// Simulate keyboard
window.SimulateKeyPress(Key.Delete, RawInputModifiers.None);For end-to-end testing with actual UI rendering, Appium can be used for cross-platform UI automation.
Community Discussion: Alternative way of UI testing for Avalonia
Avalonia 11.1+ includes comprehensive accessibility support for screen readers.
Official Announcement: Avalonia 11.1: Screen Reader Support
Platform Support:
- ✅ Windows: UI Automation API
- ✅ macOS: NSAccessibility
- ✅ Android: TalkBack (PR #17704)
⚠️ Linux: Being implemented (Issue #14275)
XAML Properties:
<Button Command="{Binding OpenFileCommand}"
AutomationProperties.Name="Open PDF File"
AutomationProperties.HelpText="Opens a file dialog to select a PDF document">
Open
</Button>
<ToggleButton IsChecked="{Binding IsRedactionMode}"
AutomationProperties.Name="Redaction Mode"
AutomationProperties.HelpText="Enable to draw redaction boxes">
<PathIcon Data="{StaticResource RedactionIcon}" />
</ToggleButton>Benefits:
- Screen reader compatibility (NVDA, JAWS, VoiceOver)
- WCAG 2.1 compliance
- Better keyboard navigation
- UI automation testability
Windows: Use Accessibility Insights macOS: Use Accessibility Inspector (Xcode) Linux: Limited tooling currently available
Collects runtime traces for performance analysis across all platforms.
Official Documentation: dotnet-trace | Microsoft Learn
What it does:
- Profiles application performance
- Tracks method calls and timing
- Monitors memory allocations
- Analyzes GC behavior
Usage:
# Collect trace from running application
dotnet trace collect --process-id $PID
# Collect trace while running tests
dotnet trace collect -- dotnet test
# Collect specific providers
dotnet trace collect --process-id $PID \
--providers Microsoft-DotNETCore-SampleProfilerAnalysis:
- Windows: Open in Visual Studio or PerfView
- Linux/macOS: Convert to speedscope format
- Cross-platform: Use dotnet-trace analyze
Real-time performance counter monitoring.
Official Documentation: dotnet-counters | Microsoft Learn
What it monitors:
- CPU usage
- Memory consumption
- GC collections
- Thread pool usage
- Custom EventCounters
Usage:
# Monitor running application
dotnet counters monitor --process-id $PID
# Monitor specific counters
dotnet counters monitor \
--process-id $PID \
--counters System.Runtime,System.Net.HttpCross-platform tracing infrastructure that powers diagnostic tools.
Official Documentation: EventPipe Overview | Microsoft Learn
Key Insight:
"EventPipe is a runtime component that can be used to collect tracing data, similar to ETW or perf_events. The goal of EventPipe is to allow .NET developers to easily trace their .NET applications without having to rely on platform-specific high-privilege components."
Benefits:
- Works on Windows, Linux, macOS
- No administrator privileges required
- Same API across platforms
- Integrates with dotnet-trace and dotnet-counters
Custom EventSource:
public sealed class RedactionEventSource : EventSource
{
public static RedactionEventSource Log = new();
[Event(1, Level = EventLevel.Informational)]
public void RedactionStarted(string fileName)
=> WriteEvent(1, fileName);
[Event(2, Level = EventLevel.Informational)]
public void RedactionCompleted(string fileName, long durationMs)
=> WriteEvent(2, fileName, durationMs);
}
// Usage in code
RedactionEventSource.Log.RedactionStarted(fileName);
// ... perform redaction ...
RedactionEventSource.Log.RedactionCompleted(fileName, sw.ElapsedMilliseconds);Industry-standard benchmarking library for .NET.
Official Repository: BenchmarkDotNet on GitHub
Used by: .NET Runtime, .NET Compiler, ASP.NET Core, and 27,400+ projects
Features:
- Micro-benchmarking with statistical analysis
- Memory allocation tracking
- Multi-framework support
- Profiler integration
Setup:
<PackageReference Include="BenchmarkDotNet" Version="0.13.12" />Example Benchmark:
public class RedactionBenchmarks
{
private ContentStreamParser _parser;
private byte[] _contentStream;
[GlobalSetup]
public void Setup()
{
_parser = new ContentStreamParser(...);
_contentStream = LoadTestContentStream();
}
[Benchmark]
public List<PdfOperation> ParseContentStream()
{
return _parser.ParseOperations(_contentStream, 792);
}
[Benchmark]
[Arguments(100)] // Small area
[Arguments(5000)] // Large area
public void RedactArea(int areaSize)
{
var area = new Rect(100, 100, areaSize, areaSize);
_redactionService.RedactArea(_page, area, _pdfPath, 150);
}
}Running:
cd BenchmarkProject
dotnet run -c ReleaseBenchmarkDotNet integrates with profiling tools:
EtwProfiler (Windows): BenchmarkDotNet Docs
[EtwProfiler] // Attribute on benchmark class
public class MyBenchmarks { }PerfCollectProfiler (Linux): Profiling on Linux
[PerfCollectProfiler]
public class MyBenchmarks { }dotTrace (JetBrains): dotTrace Integration
[DotTraceDiagnoser]
public class MyBenchmarks { }Unit Tests: Test individual components in isolation
public class CoordinateConverterTests
{
[Fact]
public void ImageSelectionToPdfPoints_ConvertsCorrectly()
{
var result = CoordinateConverter.ImageSelectionToPdfPointsTopLeft(
new Rect(100, 100, 200, 50), 150);
result.X.Should().BeApproximately(48, 0.1);
}
}Integration Tests: Test component interactions
public class RedactionIntegrationTests
{
[Fact]
public void RedactArea_RemovesTextFromPdf()
{
// Arrange: Create PDF
var pdfPath = TestPdfGenerator.CreateSimpleTextPdf("SECRET");
// Act: Redact
_redactionService.RedactArea(page, area, pdfPath, 150);
document.Save(outputPath);
// Assert: Text removed
var text = PdfTestHelpers.ExtractAllText(outputPath);
text.Should().NotContain("SECRET");
}
}UI Tests: Test ViewModel and UI behavior
[AvaloniaFact]
public async Task LoadDocument_UpdatesViewModel()
{
var vm = new MainWindowViewModel(...);
await vm.LoadDocumentAsync(testPath);
vm.DocumentName.Should().NotBeEmpty();
vm.PageCount.Should().BeGreaterThan(0);
}GitHub Actions:
- name: Run tests with coverage
run: dotnet test --collect:"XPlat Code Coverage"
- name: Profile performance
run: dotnet trace collect -- dotnet test
- name: Run benchmarks
run: cd Benchmarks && dotnet run -c Release| Tool | Purpose | Platform | Effort | Use Case |
|---|---|---|---|---|
| Avalonia.Headless | UI Testing | All | Low | Automated UI tests |
| Appium | E2E Testing | All | High | Full integration tests |
| AutomationProperties | Accessibility | Win/Mac/Android | Low | Screen reader support |
| dotnet-trace | Profiling | All | Low | Performance analysis |
| dotnet-counters | Monitoring | All | Low | Real-time metrics |
| BenchmarkDotNet | Benchmarking | All | Low | Micro-benchmarks |
| EventPipe | Tracing | All | Medium | Custom telemetry |
- Avalonia 11.1 Accessibility Features
- How to Automate UI Testing in Avalonia
- Profiling .NET on Linux with BenchmarkDotNet
Modern .NET and Avalonia provide comprehensive tooling:
Testing: ✅ Headless UI testing, pointer simulation, accessibility testing Profiling: ✅ dotnet-trace, dotnet-counters, EventPipe (all cross-platform) Benchmarking: ✅ BenchmarkDotNet with profiler integration Accessibility: ✅ AutomationProperties for screen readers
All tools work cross-platform and integrate with CI/CD pipelines. The .NET ecosystem has matured to provide py-spy-like capabilities (dotnet-trace) and comprehensive testing frameworks.