Core Framework v3 3.0.0 2025 July 13
Today, we're shipping three new releases:
- xUnit.net Core Framework v3
3.0.0
- xUnit.net Analyzers
1.23.0
(release notes) - xUnit.net Visual Studio adapter
3.1.2
(release notes)
It's been 5 weeks since the release of 2.0.3
.
As always, we'd like to thank all the users who contributed to the success of xUnit.net through usage, feedback, and code. 🎉
Release Notes
These release notes are a list of changes from 2.0.3
to 3.0.0
.
This release contains breaking changes as indicated by the major version bump. Binary compatibility with 2.x.y
packages is not guaranteed, and extensibility projects should verify whether these breaking changes affect them as they may be required to issue new versions.
Core Framework
We have added a new property
Label
to the theory data row classes and theory data attributes. Developers can set theLabel
property to influence the parameter display for test cases with theory data:- Unset (or set to
null
) will use the existing behavior:TestMethod(...parameters...)
- Set to an empty string will remove the parameter list:
TestMethod
- Set to a non-empty string will add the label to the display name:
TestMethod [LabelValue]
This will be most commonly used when combined to either label tests with complex parameters with a simpler label, or remove the parameters when combined with custom display names that already include all the necessary information for differentiating theory data rows from one another. Note that if you set this value on both the data attribute and the data row, the value from the data row will take precedence. xunit/xunit#3300
- Unset (or set to
We have added new properties (
SkipType
,SkipUnless
, andSkipWhen
) to the theory data row classes and theory data attributes. These mirror the properties that were already available onFactAttribute
, and allow data rows to be conditionally skipped. Note that if you set these values on both the data attribute and the data row, the value from the data row will take precedence. xunit/xunit#3314We have added a generic version of
ClassDataAttribute
so that you can replace[ClassData(typeof(MyData))]
with[ClassData<MyData>]
. Note that this is only supported on .NET, as .NET Framework does not support generic attributes. xunit/xunit#2945When we try to create custom attributes and it fails, we are now logging these failures via diagnostic messages. Some cases where this is most likely to happen is while registering serializers (with
[RegisterXunitSerializer]
), creating test collection factories, creatingBeforeAfterTestAttribute
instances, creating test case/collection orderers, collecting traits, among others. These new warning messages come due to a change made to way attributes are constructed in3.0.0-pre.25
in an attempt to make attribute constructor exceptions be less system-breaking.We have added two overloads to
TestContext.Current.AddAttachment
to allow developers to overwrite an existing attachment. The existing overloads will continue to throw when attempting to add an attachment when one already exists with the given name. xunit/xunit#3340Breaking change: The type of
TestContext.Current.KeyValueStorage
has changed:- 2.0.3:
Dictionary<string, object?>
- 3.0.0:
ConcurrentDictionary<string, object?>
This change was made to accommodate race conditions that could exist when reading or writing shared values from multiple tests and/or multiple extensibility points. xunit/xunit#3306
- 2.0.3:
Breaking change: For v3 test projects, we have opted to use
[CallerFilePath]
and[CallerLineNumber]
decorated ontoFactAttribute
andTheoryAttribute
rather thanCecilSourceInformationProvider
. This should improve both performance and reliability for retrieving source location information. This is a binary breaking change only; there should be no compilation issues caused by these changes, as the new parameters are (by design) decorated with default values.Tests should not try to set these values manually as they will be provided automatically by the compiler. xunit/xunit#3304
Breaking change: We have decided to deprecate
CecilSourceInformationProvider
based on performance and compatibility issues.v3 projects will utilize the compile-time source information available via
[FactAttribute]
, introduced in3.0.0-pre.15
. This is used for all execution paths: xUnit.net native runners, Microsoft Testing Platform, and VSTest (akaxunit.runner.visualstudio
).v1/v2 projects will utilize
DiaSession
from VSTest. Source information will only be available for these projects when running in the context of VSTest. v1/v2 projects running in xUnit.net native runners will not include source information, and these projects do not support Microsoft Testing Platform.
Breaking change: To fix a bug with attributes throwing in their constructors, we have changed the way we discover attributes. This "new" behavior is actually a restoration of older behavior from v2, which was required by virtue of the way we opted to allow attributes to be discovered by interface instead of concrete type. While this code is based on well tested code from v2, it's being put into new use in v3, and there may be edge case issues surrounding attribute discovery owing to this implementation change. Developers relying upon
ReflectionExtensions.GetMatchingCustomAttributes
should test to ensure that no attribute lookup bugs in their extensions have been caused by this change. xunit/xunit#3319BUG: We have fixed a memory leak in
TestContext
due to aCancellationTokenSource
object which was being allocated but not disposed. xunit/xunit#3323BUG: We have fixed an issue where the
CaptureConsole
andCaptureTrace
attributes were not usable in some circumstances. xunit/xunit#3334BUG: We have fixed an issue where F# modules with
,
in their name were causing parsing issues during type deserialization, causing them to be non-runnable in Visual Studio. xunit/xunit#3332BUG: We have fixed an issue where it was possible for us to generate two Microsoft Testing Platform log files with the same filename in some rare conditions. xunit/xunit#3333
BUG:
TestContext
was not being properly disposed, which caused a memory leak of disposable objects it contains (in particular, the cancellation token sources). xunit/xunit#3323
Assertion Library
We have added new overloads to
Assert.Throws
which allow the developer to provide an exception inspector. The inspector lambda accepts the exception (typed asException
in the non-generic versions, or typed asT
in the generic versions), and can returntrue
to accept the exception orfalse
to reject the exception. You may also throw (including using assertions) inside the lambda if you wish. xunit/xunit#2154Breaking change: We have removed an obsolete overload of
CollectionTracker.AreCollectionsEqual
. This was marked obsolete in 2.0.0 with a warning about being removed in the next major version.BUG: We have fixed an issue with
Assert.EquivalentWithExclusions
where it would ignore properties too aggressively, leading to potential false positives. xunit/xunit#3338
Microsoft Testing Platform
Microsoft.Testing.Platform dependencies have been updated to
1.7.3
.Test attachments are now supported by Test Explorer, in addition to
dotnet test
. xunit/xunit#3227We have added support for
testconfig.json
when running in Microsoft Testing Platform mode. For more information, see ourtestconfig.json
documentation. xunit/xunit#3247
Extensibility
Breaking change: We have added a new property (
Label
) toITheoryDataRow
andIDataAttribute
.Breaking change: We have added three new properties (
SkipType
,SkipUnless
, andSkipWhen
) toIDataAttribute
,ITheoryDataRow
, andIXunitTest
. The constructor forXunitTest
was updated to accommodate these new values.Breaking change: We have added two new properties (
SourceFilePath
andSourceLineNumber
) toIFactAttribute
. The newFactAttribute
constructor (mentioned above) sets these values.Any extensibility point which creates its own attributes derived (directly or indirectly) from
FactAttribute
will want to provide these same constructor arguments, or else source location information will be unavailable for tests decorated with such attributes. We have added an analyzer rule to detect this situation, since the compiler will not be helpful to discover the change.Breaking change: The existing
ExecutionErrorTestCase
constructor has been marked as obsolete, replaced by a new constructor that includes two new parameters (sourceFilePath
andsourceLineNumber
). The old constructor will be removed in the next major release.Breaking change: The existing
TestIntrospectionHelper.GetTestCaseDetails
has been marked as obsolete, replaced by a new overload that includes a newlabel
parameter. The old overload will be removed in the next major version.Breaking change: The return type from
TestIntrospectionHelper
methodsGetTestCaseDetails
andGetTestCaseDetailsForTheoryDataRow
now include two new values in the unnamed tuple return value:SourceFilePath
andSourceLineNumber
.Breaking change: We have added a new property (
TestMethodArity
) toITestCaseMetadata
andITestMethodMetadata
to support a new requirement from Microsoft Testing Platform 1.7 that requires method arity for test case metadata. This has a downstream impact onITestCaseDiscovered
,ITestCaseStarting
, andITestMethodStarting
, as well as the classes which implement all of these interfaces.Note that arity will only be available for messages from v3 test projects; this information is not back-ported for v1 or v2, and will return as
null
. microsoft/testfx#5516
Runner Utility
We have bumped up the "crash detection" idle message timeout from 5 seconds to 60 seconds, to help eliminate potential false positives related to crashing when running tests on slower machines. This value can be changed by runners by setting
XunitProject.Configuration.CrashDetectionSinkTimeout
. This configuration value is not directly adjustable by end users at this time, and there should be no noticeable change in project execution time for test projects which aren't crashing.Breaking change: We have deprecated the
AssemblyRunner
class (and all associated types) that live in theXunit.Runners
namespace, in favor of a new design that lives in theXunit.SimpleRunner
namespace. The v3 TestRunner Sample has been updated to use the new APIs. xunit/xunit#3265Notable changes include:
A new
AssemblyRunnerOptions
class is used to do all configuration of the assembly runner.This replaces the previous mixture of configuration that was spread out across the factory functions (
WithoutAppDomain
andWithAppDomain
), theAssemblyRunner
instance itself (for events), and theAssemblyRunnerStartOptions
class (for configuration).Instead, you create
AssemblyRunnerOptions
with the path to the test assembly, and then you can configure it and subscribe to the events on it. It becomes a self-contained description of your intended test run. When constructed, the configuration options are pre-populated with values from the test assembly configuration (typicallyxunit.runner.json
).The
AssemblyRunnerOptions
includes a few new metadata properties:TargetFrameworkIdentifier
(which target framework the test assembly was compiled against),TargetFrameworkVersion
(which version of the target framework the test assembly was compiled for), andXunitVersion
(which major version of xUnit.net the test assembly targets).Configuration values in
AssemblyRunnerOptions
document which major versions of xUnit.net they support, and they will not only validate the values provided but also that setting the values will be meaningful. For example, if you try to setAssertEquivalentMaxDepth
and your test assembly isn't targeting xUnit.net v3, then an exception will be thrown indicating this. Documentation example:There are three properties on
AssemblyRunnerOptions
that are only available when your runner is targeting .NET Framework and your test project is targeting .NET Framework using xUnit.net v1 or v2:AppDomain
,ShadowCopy
, andShadowCopyFolder
. These values replace the configuration available previously viaWithAppDomain
.We have dramatically increased the number of available configuration options to be better aligned with all the options now available in v3.
Test filtering is now fully supported. The old lambda-based
TestCaseFilter
has been replaced by theFilters
property onAssemblyRunnerOptions
, which allows you to specify any of the typically available filtering options. This includes simple filters (like including/excluding based on class, method, namespace, etc.) as well query filters. Note: You may not mix simple filters with query filters. Use one or the other.Most of the event information classes have been improved to include more information about the respective events. All the
Finished
event information includes the information from the relatedStarting
event information so that you no longer need to track that information across the two events.We have also added two new events:
OnDiscoveryStaring
andOnExecutionStarting
.We have added support for generating one or more of the built-in reports (XML, HTML, CTRF, etc.) at the end of test execution. You can request reports by calling
AddReport
on theAssemblyRunnerOptions
instance.The old design offered a
Start
method which immediately returned, and required the developer to periodically poll theStatus
property to determine when test execution was complete. The new design replaces this with aRun
method which returnsTask
. Developers should await theTask
to determine when the execution is complete. Note: TheAssemblyRunner
cannot issue multiple simultaneousRun
requests, though it can be reused after it's finished a previous run.
Packages
- We have removed an MSBuild property (
<IsTestProject>true</IsTestProject>
) from thexunit.v3.core
NuGet package, in anticipation of some changes that are being made by the VSTest team. dotnet/sdk#49063