A sample .NET project demonstrating how to write unit tests with NUnit and measure application performance using BenchmarkDotNet.
This repository provides a starting point for exploring automated testing, test execution, and performance benchmarking in C# applications.
- Overview
- Technologies
- Project Structure
- Prerequisites
- Getting Started
- Running Unit Tests
- Running Benchmarks
- Understanding Benchmark Results
- Author
- References
The solution separates the application code from its automated tests and benchmarking functionality.
It contains two projects:
- SampleProject: A .NET console application that includes BenchmarkDotNet.
- SampleTestProject: A test project that uses NUnit to test the application code.
This separation makes it easier to maintain application logic, validate correctness through automated tests, and investigate performance independently.
| Technology | Purpose |
|---|---|
| C# and .NET 6 | Application development |
| NUnit 3 | Unit testing framework |
| NUnit3TestAdapter | Test discovery and execution |
| Microsoft.NET.Test.Sdk | .NET test infrastructure |
| BenchmarkDotNet 0.13.1 | Performance benchmarking |
| Coverlet Collector | Test coverage collection support |
UnitTestingAndBenchmarkingExample/
├── SampleProject/
│ └── SampleProject.csproj
├── SampleTestProject/
│ └── SampleTestProject.csproj
├── SampleProject.sln
├── .gitignore
└── README.md
SampleProject
Contains the executable application project and references BenchmarkDotNet for performance measurement.
SampleTestProject
Contains the test project, references NUnit and the .NET test SDK, and references SampleProject so that application code can be tested.
SampleProject.sln
Groups the projects into a single solution for development and execution in Visual Studio or through the .NET CLI.
Before running the solution, install:
- .NET 6 SDK, or a compatible SDK capable of targeting
net6.0. - Visual Studio or another editor with .NET development support.
- Git, if you want to clone the repository.
Note: .NET 6 reached the end of its support period in November 2024. The project currently targets .NET 6, so consider upgrading it to a supported .NET version for ongoing development.
git clone https://github.com/sandygeeks/UnitTestingAndBenchmarkingExample.gitcd UnitTestingAndBenchmarkingExampledotnet restore SampleProject.slndotnet build SampleProject.slnOnce the build succeeds, you can run the unit tests and explore the benchmarking project.
The solution uses NUnit as its unit testing framework.
Run all tests in the solution with:
dotnet test SampleProject.slnTo run tests specifically from the test project:
dotnet test SampleTestProject/SampleTestProject.csprojThe test runner discovers the available NUnit tests, executes them, and reports the number of passed, failed, and skipped tests.
Unit tests help verify application behavior and detect regressions when the code changes.
The application project references BenchmarkDotNet, a .NET library designed to measure and compare the performance of code.
Run the application in Release configuration:
dotnet run --configuration Release --project SampleProject/SampleProject.csprojBenchmarkDotNet normally executes benchmarks registered by the application and produces measurement reports. For meaningful performance measurements, use the Release configuration rather than Debug.
If the application does not launch benchmarks automatically, verify that its entry point registers the appropriate benchmark class with BenchmarkDotNet.
BenchmarkDotNet can report several useful performance metrics, depending on the configured benchmark and diagnosers.
| Metric | Meaning |
|---|---|
| Mean | Average execution time across measured operations |
| Error | Estimated statistical error of the mean |
| StdDev | Standard deviation of measured execution times |
| Allocated | Memory allocated during benchmark operations, when allocation diagnostics are enabled |
Use these measurements to compare alternative implementations and understand their performance characteristics.
For fair comparisons:
- Run benchmarks in Release mode.
- Avoid unrelated CPU-intensive work during execution.
- Compare implementations using equivalent inputs and workloads.
- Run benchmarks more than once when investigating small differences.
- Consider both execution time and memory allocation.
Important: Benchmark results are measurements of a particular environment and workload, not universal performance guarantees.
Sanjit Raj Shakya
Website: https://sanjitrajshakya.com.np
- BenchmarkDotNet Documentation
- NUnit Documentation
- Microsoft Learn — Unit testing in .NET
- Microsoft Learn — .NET downloads
If you find this project useful, feel free to explore it, experiment with different testing scenarios, and compare alternative implementations.
Thank you!