FUnit.Directives 1.3.0

There is a newer version of this package available.
See the version list below for details.
dotnet add package FUnit.Directives --version 1.3.0
                    
NuGet\Install-Package FUnit.Directives -Version 1.3.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="FUnit.Directives" Version="1.3.0">
  <PrivateAssets>all</PrivateAssets>
  <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="FUnit.Directives" Version="1.3.0" />
                    
Directory.Packages.props
<PackageReference Include="FUnit.Directives">
  <PrivateAssets>all</PrivateAssets>
  <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add FUnit.Directives --version 1.3.0
                    
#r "nuget: FUnit.Directives, 1.3.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package FUnit.Directives@1.3.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=FUnit.Directives&version=1.3.0
                    
Install as a Cake Addin
#tool nuget:?package=FUnit.Directives&version=1.3.0
                    
Install as a Cake Tool

<div align="center">

FUnit

Structured Unit Testing as a File-based App

FUnit FUnit.Run FUnit.Directives <br/> build DeepWiki

</div>

 

๐Ÿ”ฌ Concept

FUnit provides structured test descriptor for file-based C# project 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 ... when ...", async () =>  // async test supported
        {
            // Write test: Arrange, Act, Assert
        });

        it("can have multiple tests within a 'describe' block", ...);
    });

    describe("Inspired by vitest", ...);
});
# Run unit test (.NET 10 can run a .cs file as a project)
dotnet run ./tests/my-test.cs

# OR use 'dnx' to run tests in current or sub folders
dnx FUnit.Run
dnx FUnit.Run --no-clean "**/*test*.cs"

 

๐Ÿ—ƒ๏ธ FUnit Descriptor Structure

For AI Coding Agents: .NET 10.0 introduced new directives for file-based app.

  • SHALL use #:project to add project reference.
  • SHALL use #:package to add nuget package reference. (* or semantic version must be specified)
  • SHALL NOT use #r or other directives formerly used for dotnet-script (.csx) files.

Unit tests should follow W.H.Y. (What, How, Yields) principle.

#:project ../src
#:package FUnit@*
#:package YourFavoriteAssertionLibrary@3.1.0

return FUnit.Run(args, describe =>
{
    // Organize tests by test subject
    describe("Test Subject", it =>
    {
        it("should be ... when ...", () =>
        {
            // Write test: Arrange, Act, Assert
        });

        // Other test cases
        it("should throw ... when ...", async () =>
        {
            // Async test is also supported
        });

        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 --project or 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)
dnx -y FUnit.Run --iterations 10

--concurrency int (Experimental)

# run max 10 tests simultaneously subject by subject
dnx -y FUnit.Run --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;
There are no supported framework assets in this package.

Learn more about Target Frameworks and .NET Standard.

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.5.0 30 1/24/2026
1.4.0 63 1/23/2026
1.3.3 64 1/22/2026
1.3.2 50 1/22/2026
1.3.1 110 1/21/2026
1.3.0 134 1/18/2026
1.2.0 156 1/13/2026
1.1.1 151 1/11/2026
1.1.0 97 1/10/2026
1.0.3 576 12/8/2025
1.0.2 262 11/16/2025
1.0.1 439 10/28/2025
1.0.0 196 10/27/2025
0.9.0 153 10/26/2025
0.8.2 155 10/26/2025
0.8.1 153 10/26/2025
0.8.0 156 10/26/2025
0.7.0 185 10/23/2025
0.6.0 230 10/20/2025
0.5.0 114 10/18/2025
0.5.0-rc.1 135 10/17/2025
0.2.3 645 9/16/2025
0.2.2 290 9/15/2025
0.2.1 274 9/15/2025
0.2.0 271 9/15/2025
0.2.0-rc.1 238 9/15/2025
0.1.2 365 9/15/2025