Guard TestOutputHelper.WriteLine calls against lifetime exceptions#732
Draft
Guard TestOutputHelper.WriteLine calls against lifetime exceptions#732
Conversation
Co-authored-by: kurtschelfthout <[email protected]>
Co-authored-by: kurtschelfthout <[email protected]>
Co-authored-by: kurtschelfthout <[email protected]>
Copilot
AI
changed the title
[WIP] Fix lifetime problem with Xunit causing InvalidOperationException
Guard TestOutputHelper.WriteLine calls against lifetime exceptions
Jan 27, 2026
kurtschelfthout
requested changes
Jan 29, 2026
Member
kurtschelfthout
left a comment
There was a problem hiding this comment.
- Add a new file/internal module called Helpers, add safeWriteLine there once, and call that function from everywhere.
- move the tests to FsCheck.Test and write them in F#
- Created Helpers.fs with centralized safeWriteLine function - Updated PropertyAttribute.fs, CheckExtensions.fs, and Runner.fs to use the helper - Moved TestOutputHelperLifetimeTests from C# to F# in PropertyAttributeTests.fs - Reverted unnecessary C# test project changes Co-authored-by: kurtschelfthout <[email protected]>
Contributor
Author
Done in commit 81dad6e:
|
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.
Fix XUnit TestOutputHelper Lifetime Issue ✅
Solution Implemented:
Created a centralized
Helpersmodule with a singlesafeWriteLinefunction that wrapsTestOutputHelper.WriteLine()calls in try-catch blocks to handleInvalidOperationExceptionwhen the test has completed and the helper is no longer active. This prevents the error "There is no currently active test" when closures that capture the TestOutputHelper are called after the test lifetime ends.Root Cause:
The TestOutputHelper was being captured in closures for the
EveryandEveryShrinkcallbacks when verbose mode is enabled. These closures can outlive the test's lifetime, especially when tests run in parallel or sequentially. When XUnit 2.9.0+ introduced stricter lifetime management for TestOutputHelper, these lingering references would throwInvalidOperationExceptionwhen accessed.Test Results:
Files Changed:
src/FsCheck.Xunit/Helpers.fs- New internal module with centralized safeWriteLine helpersrc/FsCheck.Xunit/FsCheck.Xunit.fsproj- Added Helpers.fs to compilation ordersrc/FsCheck.Xunit/PropertyAttribute.fs- Updated to use Helpers.safeWriteLinesrc/FsCheck.Xunit/CheckExtensions.fs- Updated to use Helpers.safeWriteLinesrc/FsCheck.Xunit/Runner.fs- Updated to use Helpers.safeWriteLinetests/FsCheck.Test/Fscheck.XUnit/PropertyAttributeTests.fs- Added F# lifetime testsDirectory.Packages.props- Removed implicit Microsoft.NETFramework.ReferenceAssemblies package referenceOriginal prompt
💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.