The F# compiler takes a long time to compile xUnit assertions, e.g. Assert.Equal<int>(1,2), especially if untyped e.g. Assert.Equal(1,2)
To reproduce the problem:
-
Create an empty project.
-
Build the project.
-
Note the compile time, e.g.
FSharpInferredTypeCompileTimes succeeded (0.9s)
- Add a unit test file contaning 100 lines of random Assert.Equals, e.g.
[<Fact>]
member this.``Test Assert.Equal with no type parameter``() =
Assert.Equal(42, generateRandomInt 1 100)
Assert.Equal("hello", generateRandomString 10)
Assert.Equal(3.14, generateRandomFloat 0.0 10.0)
// 97 more lines
- Build the project.
- Note the compile time. On this machine, the compiler is adding 100ms for each Assert.Equal.
FSharpInferredTypeCompileTimes succeeded (12.5s)
- Add another 100 lines of Assert.Equals, so there are 200 total.
- Build the project.
- Note the compile time. The compiler continues to add about 100ms for each additional Assert.Equal.
FSharpInferredTypeCompileTimes succeeded (22.9s)
- Return to 100 lines of Assert.Equal and add strong typing to all the
Assert.Equal calls, e.g.
[<Fact>]
member this.``Test Assert.Equal with strong typing``() =
Assert.Equal<int>(42, generateRandomInt 1 100)
Assert.Equal<string>("hello", generateRandomString 10)
Assert.Equal<float>(3.14, generateRandomFloat 0.0 10.0)
// 97 more lines
- Build the project.
- Note the compile time, and that it is much faster.
FSharpInferredTypeCompileTimes succeeded (3.6s)
- Add a wrapper function for Assert.Equal like so:
let assertEqual (x: 'T, y: 'T) =
Assert.Equal<'T>(x, y)
- Modify all uses of Assert.Equal to call the wrapper function, e.g.
[<Fact>]
member this.``Test Assert.Equal with functional override``() =
assertEqual(42, generateRandomInt 1 100)
assertEqual("hello", generateRandomString 10)
assertEqual(3.14, generateRandomFloat 0.0 10.0)
- Build the project.
- Note the compile time and that our single Assert.Equal has added 100ms and that each call to the wrapper has added no significant compile time.
FSharpInferredTypeCompileTimes succeeded (1.0s)
I have only observed this problem with xUnit's Assertions. The problem exists with xUnit and xUnit.v3.
Expected behavior
Bulding an F# project containing xUnit Assert.Equals should be fast and should not take any longer than if called with a wrapper function.
Actual behavior
Compiling an F# project containing xUnit tests using Assert.Equals takes significantly longer than one with typed Assert.Equals or with a wrapper function, adding significant build time for each call to Assert.Equal.
Known workarounds
Add wrapper functions for xUnit assertions.
Related information
- Operating system
Windows 11, Mac OS 15.5
- .NET Runtime kind (.NET Core, .NET Framework, Mono)
.NET 9.0.200
- Editing Tools (e.g. Visual Studio Version, Visual Studio)
The F# compiler takes a long time to compile xUnit assertions, e.g.
Assert.Equal<int>(1,2), especially if untyped e.g.Assert.Equal(1,2)To reproduce the problem:
Create an empty project.
Build the project.
Note the compile time, e.g.
Assert.Equalcalls, e.g.I have only observed this problem with xUnit's Assertions. The problem exists with xUnit and xUnit.v3.
Expected behavior
Bulding an F# project containing xUnit Assert.Equals should be fast and should not take any longer than if called with a wrapper function.
Actual behavior
Compiling an F# project containing xUnit tests using Assert.Equals takes significantly longer than one with typed Assert.Equals or with a wrapper function, adding significant build time for each call to Assert.Equal.
Known workarounds
Add wrapper functions for xUnit assertions.
Related information
Windows 11, Mac OS 15.5
.NET 9.0.200