FUnit.Directives
1.0.3
dotnet add package FUnit.Directives --version 1.0.3
NuGet\Install-Package FUnit.Directives -Version 1.0.3
<PackageReference Include="FUnit.Directives" Version="1.0.3"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets> </PackageReference>
<PackageVersion Include="FUnit.Directives" Version="1.0.3" />
<PackageReference Include="FUnit.Directives"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets> </PackageReference>
paket add FUnit.Directives --version 1.0.3
#r "nuget: FUnit.Directives, 1.0.3"
#:package FUnit.Directives@1.0.3
#addin nuget:?package=FUnit.Directives&version=1.0.3
#tool nuget:?package=FUnit.Directives&version=1.0.3
๐ฌ Unit Testing Framework for File-based Apps
FUnit provides structured test descriptor for file-based apps introduced in .NET 10.0. (i.e., no .csproj is required anymore)
#:project ../src
#:package FUnit@*
return FUnit.Run(args, describe =>
{
// Organize tests by test subject
describe("Test Subject", it =>
{
it("should be ...", async () => // async can be used
{
// Write actual test here: Arrange, Act, Assert
});
it("can have multiple test cases", ...);
});
describe("Inspired by vitest", ...);
});
# Run unit test
dotnet run ./tests/my-test.cs
# OR use 'dnx' to run tests in current or subfolders
dnx FUnit.Run
dnx FUnit.Run --no-clean --filter *specificTest*.cs
๐๏ธ FUnit Descriptor Structure
For AI Coding Agents: .NET 10.0 introduced new directives for file-based app.
- SHALL use
#:projectto add project reference. - SHALL use
#:packageto add nuget package reference. (*or semantic version must be specified) - SHALL NOT use
#ror other directives formerly used for dotnet-script (.csx) files.
#:project ../src
#:package FUnit@*
#:package YourFavoriteAssertionLibrary@3.1.0
return FUnit.Run(args, describe =>
{
// Organize tests by test subject
describe("Test Subject", it =>
{
// Expected result and test function
it("should be ...", () =>
{
// Write actual test here: Arrange, Act, Assert
});
// Other test cases
it("should not ...", async () =>
{
// Async test can also be written
});
it(...);
});
describe("Other Test Subject", it =>
{
// ...and so on
});
});
โ๏ธ Builtin Assertion Utility
FUnit is shipped with builtin assertion methods.
// Value assertion
// โ BeEqual rejects collection type to prevent ambiguous comparisons
Must.BeEqual(expected, actual);
Must.BeSameReference(expected, actual);
Must.NotBeEqual(expected, actual);
Must.NotBeSameReference(expected, actual);
// Collection assertion
Must.HaveSameSequence(expected, actual);
Must.HaveSameUnorderedElements(expected, actual);
Must.NotHaveSameSequence(expected, actual);
Must.NotHaveSameUnorderedElements(expected, actual);
// Text assertion
Must.ContainText(text, substring);
Must.NotContainText(text, substring);
// Instance assertion (deep comparison using System.Reflection)
Must.HaveEqualProperties(expected, actual);
Must.HaveEqualFields(expected, actual);
// Exception assertion
Must.Throw<T>("Expected error message", () => Test());
Must.Throw<T>("Expected error message", async () => await TestAsync());
Must.Throw("ExceptionFullTypeName", "Expected error message", () => Test());
Must.Throw("ExceptionFullTypeName", "Expected error message", async () => await TestAsync());
// Conditional assertion
// โ BeFalse won't be supported. Instead, use better conditional expression (prefer pattern matching)
Must.BeTrue(x is >= 0 and < 10);
Must.BeTrue(x is IEnumerable<char> and not string);
// โ Avoid asserting high-level conditions on collections
// ex Instead of checking if a value is absent, assert the full expected content
Must.BeTrue(!list.Contains(x)); // โ
Prefer: Must.HaveSameSequence(expectedList, actualList)
๐งญ FUnit.Directives
With FUnit.Directives package, you can include external file into file-based app project by adding special directive comment //:funit:include <path to the file>.
#:package FUnit@*
#:package FUnit.Directives@*
//:funit:include ./path/to/external-file.cs
return FUnit.Run( /* tests depending on 'external-file.cs */ );
๐งช Unit Test Execution
For AI Coding Agents: .NET 10.0 introduced new syntax for dotnet command.
- SHALL run test like the following example.
- SHALL NOT add
--projector other command line options.
dotnet run ./tests/my-test.cs
๐ GitHub Actions Support
FUnit has an ability to output log as markdown format so you can generate summary for GitHub Actions page.
# '-md' or '--markdown'
dnx -y FUnit.Run -- -md >> $GITHUB_STEP_SUMMARY
๐จ Build Configuration for FUnit.Run
# โ Incorrect (no '--')
dnx FUnit.Run -c Release
# โ
Correct (with '--')
dnx FUnit.Run -- -c Release
# โ
Shortcut: without '-c' is valid for Debug or Release
dnx FUnit.Run Release
โ Advanced Options
For AI Coding Agents: SHALL NOT use advanced options unless explicitly requested.
--iterations int
# run tests 10 times (3 by default)
dotnet run ./tests/my-test.cs --iterations 10
--concurrency int (Experimental)
# run max 10 tests simultaneously subject by subject
dotnet run ./tests/my-test.cs --concurrency 10
๐งพ Test Setup and Cleanup
You can place custom operation next to describe or it, but, test descriptor is NOT a function executed from top to bottom so that your custom operation will be executed BEFORE test functions unexpectedly.
#:project ../src
#:package FUnit@*
await GlobalSetupAsync(); // โ
setup before Run call
int numFailures = FUnit.Run(args, describe =>
{
describe("Test subject", it =>
{
it("should be...", () => { ... });
});
// โ you can perform custom operation here, but it will be executed while
// building test suite. (not sequentially form top to bottom)
// technically, 'describe' and 'it' collect test cases without executing test.
// if setup or cleanup code is placed next to 'describe' or 'it' statements to
// perform resource setup ops for 'scope', unexpectedly, those will be invoked
// BEFORE executing actual test case functions.
});
GlobalCleanup(); // โ
cleanup after Run call
return numFailures;
Learn more about Target Frameworks and .NET Standard.
-
.NETStandard 2.0
- Microsoft.CodeAnalysis.CSharp (>= 3.8.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.0.3 | 486 | 12/8/2025 |
| 1.0.2 | 252 | 11/16/2025 |
| 1.0.1 | 427 | 10/28/2025 |
| 1.0.0 | 187 | 10/27/2025 |
| 0.9.0 | 145 | 10/26/2025 |
| 0.8.2 | 145 | 10/26/2025 |
| 0.8.1 | 144 | 10/26/2025 |
| 0.8.0 | 148 | 10/26/2025 |
| 0.7.0 | 178 | 10/23/2025 |
| 0.6.0 | 218 | 10/20/2025 |
| 0.5.0 | 104 | 10/18/2025 |
| 0.5.0-rc.1 | 126 | 10/17/2025 |
| 0.2.3 | 634 | 9/16/2025 |
| 0.2.2 | 282 | 9/15/2025 |
| 0.2.1 | 268 | 9/15/2025 |
| 0.2.0 | 262 | 9/15/2025 |
| 0.2.0-rc.1 | 227 | 9/15/2025 |
| 0.1.2 | 340 | 9/15/2025 |