Yeehaw, fellow developer! There's a new sheriff in Testing Town, and its name is TUnit. This newcomer promises to bring order to the wild west of unit testing in .NET 8. Are you ready for a framework showdown? Draw your keyboard and get ready!
TLDR (Summary)
- TUnit is a new unit testing framework for .NET 8.
- It's based on NUnit and XUnit.
- It offers a fluid and expressive syntax for assertions.
- It runs tests in parallel by default.
- It's faster than NUnit and XUnit.
- It provides clear and easy-to-understand error messages.
- It allows data-driven tests with the Arguments attribute.
- It's available as a NuGet package and is compatible with Visual Studio, Rider, and VS Code.
- Visit TUnit to learn more.
Who is this TUnit stranger?
TUnit is no stranger to Testing Town. It's based on the best of NUnit and XUnit but gives up on the problems that can arise from compatibility with older versions of .NET. It's only available from version 8 onwards as it's built on Microsoft's new testing platform (Microsoft.Testing.Platform), and that makes your tests run faster than the best steed you've ever seen.
Unit tests, integration tests, acceptance tests... nothing makes our sheriff tremble.
You can find it for the latest versions of Visual Studio as well as in Rider or VS Code as a NuGet package: TUnit nuget
TUnit in action: Cleaning up the streets of Testing Town
But enough talk. It's time to see what TUnit is and what it's capable of.
This is a simple unit test where our sheriff will capture Billy the Kid and get a $10,000 reward for it.
using TUnit.Assertions;
using TUnit.Assertions.Extensions;
using TUnit.Core;
public class SheriffTests
{
[Test]
public async Task CaptureBandit_KnownBandit_ShouldIncreaseReward()
{
// Arrange
var sheriff = new Sheriff("Wyatt Earp");
var bandit = new Bandit("Billy the Kid", reward: 10000);
// Act
var result = sheriff.CaptureBandit(bandit);
// Assert
await Assert.That(result.Reward).IsEqualTo(10000);
}
}
- If you notice, TUnit still uses the AAA (Arrange, Act and Assert) pattern that we use in other testing frameworks.
- The Asserts use a fluent syntax to make it much clearer and more readable what they are validating.
-
And although we only have one test here, tests are always run in parallel by default. If any of your tests should not be run in parallel, you need to add the
[NotInParallel]
attribute to it.[Test, NotInParallel] public async Task CaptureBandit_KnownBandit_ShouldIncreaseReward()
The new sheriff's weapons: TUnit Assertions
Every good sheriff needs an arsenal, and TUnit doesn't fall short. In the previous example, you've already met That
and IsEqualTo
, but here are a few more.
That().IsNullOrEmpty()
That().IsNullOrWhitespace()
That().IsNotNull()
That().IsPositive()
That().ThrowsException()
There are many more, and even if you don't find the one you need, you can create your own Assert by inheriting from the class
AssertCondition<TActual, TExpected>
where TActual is the object to be validated and TExpected is the expected value.
Override the Passes
method with the validation you need to perform
private protected override bool Passes(TActual? actualValue, Exception? exception)
And the GetFailureMessage
method to display the error message you need
protected internal override string GetFailureMessage()
Another interesting point is that you can create more complex or complete validations with the And
and Or
properties
[Test]
public async Task MyTest()
{
var result = 1 + 2;
await Assert.That(result)
.IsNotNull()
.And.IsPositive()
.And.IsEqualTo(3);
}
Well, I'll be! If this doesn't deserve a good swig of sarsaparilla!
The great duel: TUnit vs NUnit vs xUnit
Feature | TUnit | NUnit | xUnit |
---|---|---|---|
Syntax | Fluid and expressive | Traditional | Modern but less expressive |
Speed | πππ | ππ | ππ |
Learning curve | Smooth as aged whiskey | Familiar as an old revolver | Somewhat complicated at first |
.NET 8 Integration | Perfect as a tailored suit | Good | Good |
Error messages | Clear as river water | Sometimes cryptic | Better than NUnit |
Community | Small but growing | Large and established | Large and active |
Plugins | Few but powerful | Abundant | Moderate |
Why is TUnit the new sheriff we need?
-
Syntax that makes you fall in love: Writing tests with TUnit is as satisfying as winning a duel at high noon. Simple, straightforward, and using fluent syntax.
[Test] public void Bank_WithdrawMoney_ShouldReduceBalance() { var account = new BankAccount(initialBalance: 100); account.WithdrawMoney(50); account.Balance.That().IsEqual(50); }
-
Speed of a gunslinger: Your tests will run faster than a bank robber being chased by the law.
Method | Mean | Error | StdDev |
---|---|---|---|
TUnit_AOT | 239.1 ms | 17.49 ms | 51.58 ms |
TUnit | 598.0 ms | 22.00 ms | 64.88 ms |
NUnit | 14,188.5 ms | 282.69 ms | 495.11 ms |
xUnit | 14,397.4 ms | 285.65 ms | 684.40 ms |
MSTest | 14,396.9 ms | 285.20 ms | 370.85 ms |
-
Error messages that speak your language: No hieroglyphics here. TUnit tells you what happened with the clarity of a Sunday preacher.
-
Data-driven tests: Repeat your tests as many times as you want with different data sets without going crazy using the
Arguments
attribute.[Test] [Arguments(1, 1, 2)] [Arguments(1, 2, 3)] [Arguments(2, 2, 4)] [Arguments(4, 3, 7)] [Arguments(5, 5, 10)] public async Task MyTest(int value1, int value2, int expectedResult) { var result = value1 + value2; await Assert.That(result).IsEqualTo(expectedResult); }
Conclusion: Are you ready to join the new law in Testing Town? π
TUnit isn't just another testing framework, it's a revolution in the wild west of development. It's fast, intuitive, and more fun than a Saturday night rodeo.
NUnit and xUnit are like those old sheriffs who have kept the peace for years. Respectable, reliable, but perhaps a bit tired. TUnit is the new sheriff in town, bringing fresh ideas and an attitude that makes testing your code more exciting than a sunset shootout. It's true that it's new in town and will need some time to see if it settles in and earns the respect it deserves.
So, what do you say, cowboy? Are you ready to hang up your old NUnit or xUnit badge and join the new law in Testing Town? TUnit is waiting for you, and together, you'll make bugs tremble in fear at the sound of your footsteps.
And you? Do you dare to draw TUnit in your next project? Or will you stick to your old reliable like a cowboy to his favorite horse?
Remember: in Testing Town, the only law is code quality. And with TUnit as your deputy, that law will be enforced... to the letter! π€ π
If you want to know more about it, check out its page: TUnit or if you feel like being a deputy sheriff, try making your contributions to the project's Git repository Repository