Repository navigation
chore: upgrade xunit from v2 to v3 - #4623
Merged
Merged
Conversation
Contributor
Python Type Checking Results (Pyright)
Excluded files with errors (4 files)These files have known type errors and are excluded from CI. Remove from
|
MangelMaxime
force-pushed
the
main
branch
2 times, most recently
from
June 30, 2026 21:38
7ceced2 to
c85af32
Compare
MangelMaxime
force-pushed
the
main
branch
2 times, most recently
from
September 8, 2026 07:01
453bed5 to
19a6522
Compare
dbrattli
force-pushed
the
chore/xunit-v3
branch
from
October 11, 2026 16:51
6a65b18 to
fdd1bc2
Compare
ncave
reviewed
Oct 11, 2026
| () | ||
|
|
||
| // [<OuterAttr("cfg", [|"not(feature = \"no_std\")"|])>] | ||
| #if FABLE_COMPILER |
Collaborator
There was a problem hiding this comment.
If you rebase, you can just delete the main endpoint. See #5055.
Collaborator
Author
There was a problem hiding this comment.
Thanks @ncave. I tried to get this working again. Been uncertain about merging this since its technically unsupported by Xunit, but I guess we do not have much alternative 🤔 Ref: xunit/xunit#3455
Replace the deprecated xunit v2 (`XUnit` 2.9.3) package with `xunit.v3` 3.2.2 in the Beam, Php, Python and Rust test projects. v3 test projects are self-executing, so each project now sets `OutputType=Exe` (added to Rust and Php; Python and Beam already had it) and the .NET-side `[<EntryPoint>]` is dropped in favour of the runner entry point generated by xunit.v3: - Rust `main.fs` is also transpiled to Rust's `fn main`, so its entry point is guarded with `#if FABLE_COMPILER` rather than removed. - Python/Beam/Php had the entry point only in the .NET (`#else`) branch of `Main.fs`, which is removed. `xunit.runner.visualstudio` 3.1.5 is already v3-compatible, so `dotnet test` continues to work. Test sources need no changes: `Xunit.FactAttribute`, `Assert.Equal` and `Assert.NotEqual` are unchanged in v3. Verified with `dotnet test -c Release`: Rust (2449), Python (2266) and Beam (2439) pass. The Php project has pre-existing compile errors on .NET unrelated to xunit and is not run by the build system. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
CI revealed that the Fable transpilation of the Rust tests failed with
FS0433 ("EntryPointAttribute must be the last declaration in the last
file"). When Fable cracks a project it defines FABLE_COMPILER and runs
the CoreCompile target, which triggers xunit.v3's _XunitAttachSourceFiles
target. That appends a generated entry point and the built-in runner
reporters after the project's own source files. For Rust this collides
with the `[<EntryPoint>]` in tests/src/main.fs (and those sources also
reference runtime types Fable cannot transpile).
Disable both attached source files for the Fable build only, keyed off
the FABLE_COMPILER MSBuild property that Fable's MSBuildCrackerResolver
passes (`/p:FABLE_COMPILER=True`). On .NET the properties keep their
defaults, so xunit.v3 still generates the test runner entry point.
Verified `dotnet test -c Release` (Rust 2449 passing) and the Fable
transpile (Rust/Python/Beam) all succeed with no xunit sources leaking
into the transpiled output.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Several MailboxProcessor/async tests assert from inside a fire-and-forget `Async.StartImmediate`, whose continuation can run after its test collection has been torn down. xunit.v3 reports such background-thread exceptions as catastrophic failures and exits non-zero (xunit v2 silently ignored them). With parallel test collections this surfaces on Windows as "Catastrophic failure: Assert.Equal() ... Expected 42, Actual 0". Add tests/Python/xunit.runner.json disabling test-collection parallelization so each collection fully drains before the next runs. This is the only xunit suite that runs on Windows in CI (Rust/Beam/Php .NET tests run on Linux only; the JS suite uses Expecto). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…feedback - Add xunit.runner.json to Beam and Php: their tests use the same fire-and-forget Async.StartImmediate pattern as Python, so they are exposed to the same xunit.v3 catastrophic background-exception failures. - Collapse the now-identical #if FABLE_COMPILER branches in Beam/Php/Python Main.fs and add the missing trailing newlines. - Compress the .fsproj comments explaining the cracking workaround. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
dbrattli
force-pushed
the
chore/xunit-v3
branch
from
October 12, 2026 06:18
546a3cf to
a47b83e
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Upgrade the Beam, PHP, Python, and Rust .NET tests to xUnit v3 4.0.2 and Visual Studio runner 4.0.1. Use
xunit.v3.mtp-offto preserve VSTest on .NET 10.Main.fsfiles and Rust’s application entry point; Rust uses Cargo’s library test harness.no_mainonly for crates with an application entry point, sono_stdlibraries retain Cargo’s test harness.Validation:
no_stdnative tests passed (1 ignored in each). Theno_stdexecutable smoke check also passed.Main.fs.git diff --checkpassed.