Migrating Unit Tests from v2 to v3 2025 April 12
This migration guide aims to be a comprehensive list helping developers migrate from xUnit.net v2 to v3. This guide is focused on what to expect for unit test authors. Extensibility authors will want to review this document, and then read the migration guide specifically for extensibility authors.
Because this is a comprehensive guide, you may wish to only skim parts of it, and use search functionality to find information on specific issues that arise, rather than trying to read the guide entirely. You should read the first informational section titled "Architectural Changes", then follow the next three sections related to (a) updating NuGet packages, (b) updating to create an executable instead of a library, and (c) updating your target framework. All sections after that should be consider reference material.
In addition to this migration document (which only covers the differences between v2 and v3), we have a parallel document which covers what's new in v3. The "What's New" document describes newly available features (including information on the best way to create new xUnit.net v3 projects), and should be consulted after you've successfully migrated your project from v2 to v3.
The current builds are:
Package | NuGet Version | CI Version |
---|---|---|
xunit.v3.* |
||
xunit.analyzers |
||
xunit.runner.visualstudio |
Note that while we attempt to ensure that CI builds are always usable, we cannot make guarantees. If you come across issues using a CI build, please let us know!
Architectural Changes
Before we talk about the migration process, we need to provide information about architectural changes that have occurred between v2 and v3 that impact you as a developer.
New minimum runtime requirements
We have set new minimum runtime requirements for xUnit.net v3:
- .NET Framework 4.7.2 (or later)
- .NET 8 (or later)
Our target frameworks for v3 currently are:
- .NET Standard 2.0 (
netstandard2.0
) - .NET Framework 4.7.2 (
net472
) - .NET 8 (
net8.0
)
Also new for v3: Mono is officially supported on Linux and macOS for .NET Framework test projects. While it did often work with v1 and v2, we do officially test and verify with it now.
For a complete list of which packages target which frameworks, please see this issue.
Stand-alone executables
Test projects in v2 are library projects, and runners were required to run the tests. Those runners loaded the assemblies into their own address space and ran them from there. This was a design from back in .NET Framework days, where Application Domains could be used as a semi-effective isolation layer between the runner and the unit test code. This relatively complex isolation system was removed from .NET Core, so it's no longer available. Application Domains not only solved a very real isolation problem (and loading/unloading problem), but also a much more significant dependency resolution problem.
Test projects in v3 are stand-alone executables now, capable of running themselves. Rather than worrying about dependency resolution at runtime, we allow the compiler to do its job for us. The isolation of running your tests in a separate process is significantly simpler and more effective than Application Domains were in .NET Framework, and works for .NET as well.
When you build a v3 test project, the result is directly executable.
- For .NET Framework projects, the resulting
.exe
file is your unit test project and can be run - For .NET projects, the resulting
.dll
file is your unit test project, and the build process also creates a.exe
file (or extension-less executable, on Linux and macOS) that can be used to run your test project. (It's important to remember that the executable for .NET projects is just a stub launcher; the actual unit tests live inside the.dll
, and when using any multi-assembly runner, you will pass the path to the.dll
file for .NET projects, not the.exe
file.)
If you run the executable without any command line options, all your tests will run:
You can pass -?
to the executable for a complete list of command line switches that are available. The list will be very similar to the console runner's command line options, except slightly reduced because of the fact that you're only running a single test assembly.
If you want to build and run in a single step, dotnet run
will work with both .NET Framework and .NET test projects. Just bear in mind that passing command line options with dotnet run
requires prefixing options for the test project with --
. For example, if you want to generate an XML report of the test run, these two are equivalent:
$ dotnet build
$ .\bin\Debug\TestProject.exe -xml results.xml
$ dotnet run -- -xml results.xml
Only SDK-style projects are supported
While we are aware that you may be able to make xUnit.net v3 work with older, pre-SDK-style projects, this is not a supported scenario by our team.
async void tests are no longer supported
Tests which are async void
will be fast-failed at runtime to indicate that their signatures need to be updated from void
to either Task
or ValueTask
.
IAsyncLifetime
now inherits from IAsyncDisposable
and disposal guidelines have been updated
In v2, IAsyncLifetime
defined its own DisposeAsync
method, and if you implemented both IAsyncLifetime
and IDisposable
, we would call both DisposeAsync
and Dispose
.
In v3, IAsyncLifetime
now inherits IAsyncDisposable
, so the DisposeAsync
method comes from there. We are also now following framework guidance which says that when an object implements both IAsyncDisposable
and IDisposable
, you should only call one or the other, and not both. For xUnit.net, that means it will call DisposeAsync
but not Dispose
. This is true even for objects which implement both IAsyncDisposable
and IDisposable
, regardless of whether they implement IAsyncLifetime
or not.
This could be a breaking change if you were previously relying on us calling both.
Attribute instance lifetime may differ
Due to differences in the way v2 and v3 acquire attribute instances, it may appear that we are now caching attribute instances where we previously did not. The truth is that the previous behavior (of over-creating attribute instances) was actually the bug in this scenario, as it differs from the normal .NET behavior (where attribute instances are cached when they're first created).
Migrating to v3 Packages
Most of the packages for v3 Core Framework have moved to new names that start with xunit.v3
.
Change the following package references (and use versions from the table at the top of this page):
v2 package | v3 package |
---|---|
xunit |
xunit.v3 |
xunit.abstractions |
Remove, no longer required |
xunit.analyzers |
Unchanged |
xunit.assert |
xunit.v3.assert |
xunit.assert.source |
xunit.v3.assert.source |
xunit.console |
Remove, no longer supported |
xunit.core |
xunit.v3.core |
xunit.extensibility.core xunit.extensibility.execution |
xunit.v3.extensibility.core (*) |
xunit.runner.console |
xunit.v3.runner.console |
xunit.runner.msbuild |
xunit.v3.runner.msbuild |
xunit.runner.reporters xunit.runner.utility |
xunit.v3.runner.utility (*) |
xunit.runner.visualstudio |
Make sure to pick up a 3.x.y version |
Note: In some cases multiple libraries/packages were merged together into a single new library/package, as denoted in the table above with (*).
If you want to use the MSBuild runner, we now ship both a .NET Framework and .NET Core/.NET version in the same package. It will dynamically select the correct version depending on whether you use the .NET Framework MSBuild or the .NET MSBuild (via dotnet build
or dotnet msbuild
). However, the .NET version only supports v3 test projects. If you need to still run v1 and/or v2 test projects, you must use the .NET Framework version. (Mono ships with a .NET Framework version of MSBuild, so all comments about .NET Framework also apply to Mono.)
Why did we change the package names?
We changed the package naming scheme from xunit.*
to xunit.v3.*
for two primary reasons and one secondary reason:
We wanted users to make a conscious choice to upgrade and understand what the scope of that work is, rather than being offered a NuGet package upgrade in Visual Studio and then have everything be broken without being told why.
We have frequently been asked to observe SemVer for our package versions, which has been impossible previously. Our package naming and versioning system predates SemVer, and trying to adopt it after the fact would be painful. The
2
in the2.x.y
package versioning scheme implied a product version but it was living in the major version of the package. The new package name allows the v3 product version to live in the package name instead of the major version, and this allows us to evolve those package versions according to SemVer without implying a new production version has been released.
The secondary reason was:
- As shown above, some packages have been merged (and new intermediate packages have been introduced). We previously tried the "upgrade an obsoleted package" strategy from v1 -> v2 with the
xunit.extensions
package and found that process less than ideal for most users. This is not an area where NuGet is particularly helpful. We would've preferred that we could have automatically removedxunit.extensions
rather than having a v2 version in place with no code inside as a dead reference. By having users follow this migration guide, we can clearly tell them which packages changed and which should be removed.
Convert to Executable Project
Update your project file (i.e., .csproj
) and change OutputType
from Library
to Exe
. You may need to add OutputType
if it's not present, since Library
is the default value:
<PropertyGroup>
<OutputType>Exe</OutputType>
</PropertyGroup>
Update Target Framework
Per the new minimum target framework versions, make sure to update your target framework(s) if you're currently targeting something that's no longer supported.
At this point, you should be able to successfully run dotnet restore
.
From this point forward, we will discuss the changes you'll see, and where common compilation errors might occur.
Removal of xunit.abstractions
The xunit.abstractions
package in v2 was used to communicate across the Application Domain between unit tests and unit test runners. Now that the runner lives in the same process with your unit test project, this abstraction layer is no longer necessary.
There are several abstraction interfaces that were previously in the Xunit.Abstractions
namespace that have been moved to new namespaces. Because xunit.v3.runner.utility
still needs to link against xunit.abstractions
to be able to run v2 tests, these types all needed to move into new namespaces to prevent naming collisions with the v2 types.
The follow types have been moved to Xunit
(in xunit.v3.extensibility.core
):
ITestOutputHelper
The following types have been moved to Xunit.Runner.Common
(in xunit.v3.runner.common
):
ISourceInformationProvider
The following types have been moved to Xunit.Sdk
(in xunit.v3.common
):
IAfterTestFinished
IAfterTestStarting
IBeforeTestFinished
IBeforeTestStarting
IDiagnosticMessage
(note that internal diagnostic messages now sendIInternalDiagnosticMessage
)IDiscoveryCompleteMessage
(renamed toIDiscoveryComplete
)IErrorMessage
IFailureInformation
(renamed toIErrorMetadata
)IFinishedMessage
(renamed toIExecutionSummaryMetadata
)IMessageSink
IMessageSinkMessage
ITest
ITestAssembly
ITestAssemblyCleanupFailure
ITestAssemblyFinished
ITestAssemblyMessage
ITestAssemblyStarting
ITestCase
ITestCaseCleanupFailure
ITestCaseDiscoveryMessage
(renamed toITestCaseDiscovered
)ITestCaseFinished
ITestCaseMessage
ITestCaseStarting
ITestClass
ITestClassCleanupFailure
ITestClassConstructionFinished
ITestClassConstructionStarting
ITestClassDisposeFinished
ITestClassDisposeStarting
ITestClassFinished
ITestClassMessage
ITestClassStarting
ITestCleanupFailure
ITestCollection
ITestCollectionCleanupFailure
ITestCollectionFinished
ITestCollectionMessage
ITestCollectionStarting
ITestFailed
ITestFinished
ITestFrameworkDiscoveryOptions
ITestFrameworkExecutionOptions
ITestFrameworkOptions
ITestMessage
ITestMethod
ITestMethodCleanupFailure
ITestMethodFinished
ITestMethodMessage
ITestMethodStarting
ITestOutput
ITestPassed
ITestResultMessage
ITestSkipped
ITestStarting
IXunitSerializable
IXunitSerializationInfo
The following types have been moved to Xunit.v3
(in xunit.v3.extensibility.core
):
ITestFramework
ITestFrameworkDiscoverer
ITestFrameworkExecutor
The following types have been removed:
IAssemblyInfo
IAttributeInfo
IExecutionMessage
IMethodInfo
IParameterInfo
IReflectionAssemblyInfo
IReflectionAttributeInfo
IReflectionMethodInfo
IReflectionParameterInfo
IReflectionTypeInfo
ISourceInformation
(replaced withSourceInformation
)ITypeInfo
Changes to Assertion Library
By and large, the assertion library in v3 is a small superset of the assertion library in v2 2.9. There are new assertions as well as overloads to existing assertions that might conflict with any custom assertions you've added and/or might cause compilation issues due to ambiguous overloads now available.
A complete list of what was added is available in the what's new in v3 document.
Changes to Core Framework
The core framework has undergone some extension re-working internally. We aimed to make as few disruptive changes as possible, trying to limit those to where it was unavoidable and/or the usability improvement warranted the change. We hope that the vast majority of these will involve just modifying or cleaning up using
statements.
Attributes that took type name and assembly name strings
There were several attributes in the system that allowed you to take type names as two strings: the fully qualified type name, and the name of the assembly where that type resides. This was to support source-based test discovery, which is a feature that has been removed from v3.
These attributes have been updated so that their constructors now simply take a Type
, and you can use typeof
to specify the type of the object.
For example:
[assembly: CollectionBehavior("MyNamespace.MyCollectionFactory", "MyAssembly")]
can be converted to:
[assembly: CollectionBehavior(typeof(MyCollectionFactory))]
The list of the affected attributes include:
CollectionBehaviorAttribute
TestCaseOrdererAttribute
TestCollectionOrdererAttribute
TestFrameworkAttribute
Removal of reflection abstractions
The removal of reflection abstractions means that many previous splits between attributes and discoverers have been collapsed, and the attributes become responsible for their own behavior rather than relying on discoverers (which were previously written in terms of the reflection abstractions rather than depending on compiled code).
One obvious example of this is the removal of IDataDiscoverer
(previously in Xunit.Abstractions
) and DataDiscoverer
(previously in Xunit.Sdk
). The IDataDiscoverer.GetData
method has been moved to IDataAttribute.GetData
, and becomes an abstract method on the base DataAttribute
class. The previous method was given an IAttributeInfo
(which pointed to the DataAttribute
-derived attribute) and IMethodInfo
(which pointed to the test method); the updated method provides access to the MethodInfo
(rather than the reflection abstraction version), and also to a disposal tracker so that it can add any data that it creates which might need to be disposed when cleaning up.
If you're looking for a type that has disappeared and it's a discoverer, chances are the thing it previous discovered is now responsible for describing itself, rather than relying on an external discoverer.
Namespace changes
Many of the namespace changes here have been done in the name of consistency. Generally speaking, when you see a type that now lives in the Xunit.Sdk
namespace, it comes from xunit.v3.common
, and when you see it in the Xunit.v3
namespace, it comes from xunit.v3.extensibility.core
.
The concrete test messages in the
Xunit.Sdk
namespace (for example,DiagnosticMessage
) have moved to theXunit.v3
namespace. In the case where messages had non-empty constructors (for example,ErrorMessage
) they have been converted to a single parameterless constructor (for serialization/deserialization purposes), and helper static creation methods likeFromException
have been added to replace the previous constructor usage.The runner classes (i.e.,
TestAssemblyRunner
,TestCollectionRunner
, etc.) have moved fromXunit.Sdk
toXunit.v3
. The non-abstract classes (i.e.,XunitTestAssemblyRunner
,XunitTestCollectionRunner
, etc.) have been converted to singletons. As such, their constructors have been replaced byRunAsync
methods which accept the information previously passed to the constructor. Their state is now stored in context classes that are constructed and passed between layers. The base runner classes now also have expanded generic types required to match the new context requirements.CollectionPerAssemblyTestCollectionFactory
andCollectionPerTestClassTestCollectionFactory
have moved from theXunit.Sdk
to theXunit.v3
namespace.The abstract
DataAttribute
class has moved from theXunit.Sdk
to theXunit.v3
namespace.DiscoveryCompleteMessage
has been renamed toDiscoveryComplete
, and moved fromXunit.Sdk
toXunit.v3
.DisplayNameFormatter
has moved fromXunit.Sdk
toXunit.v3
.ExceptionAggregator
has moved fromXunit.Sdk
toXunit.v3
, and been converted to astruct
rather than aclass
. TheRunAsync
methods have been converted fromTask
toValueTask
to align with the framework moving toValueTask
internally.ExecutionErrorTestCase
has moved fromXunit.Sdk
toXunit.v3
, and its primary constructor has been updated.ExecutionTimer
has moved fromXunit.Sdk
toXunit.v3
, made static, and itsAggregate
methods have been renamed toMeasure
. The async versions have converted from acceptingTask
to acceptingValueTask
andValueTask<T>
. These methods now return the measured time rather than aggregating a count inside the timer itself.ExtensibilityPointFactory
has moved fromXunit.Sdk
toXunit.v3
and been completely overhauled, given the removal of the reflection abstractions when the source-based discovery feature was removed from v3.ITestCaseOrderer
has moved fromXunit.Sdk
toXunit.v3
, andOrderTestCases
now both accepts and returnsIReadOnlyCollection<TTestCase>
instead ofIEnumerable<TTestCase>
.ITestCollectionOrderer
has moved fromXunit
toXunit.v3
, andOrderTestCollections
now both accepts and returnsIReadOnlyCollection<TTestCollection>
instead ofIEnumerable<TTestCollection>
.IXunitTestCaseDiscoverer
has moved fromXunit.Sdk
toXunit.v3
and theDiscover
method has been made async.IXunitTestCollectionFactory
has moved fromXunit.Sdk
toXunit.v3
.MaxConcurrencySyncContext
has moved fromXunit.Sdk
toXunit.v3
.TestCollectionComparer
has moved fromXunit.Sdk
toXunit.v3
and been made generic.
Types removed
The
AsyncTestSyncContext
class which madeasync void
tests work has been removed.AssemblyTraitAttribute
has been removed andTraitAttribute
can be used on assemblies now.LongLivedMarshalByRefObject
(in theXunit
namespace) has been removed from the core framework, since v3 does not support running in Application Domains.PlatformSpecificAssemblyAttribute
has been removed, asxunit.v3.extensibility.core
is based purely onnetstandard2.0
now rather than the previous multi-targetedxunit.execution.*
libraries.PropertyDataAttribute
, which had been obsoleted in favor ofMemberDataAttribute
, has been removed.Reflector
(and all theReflectionXyz
classes it returned) has been removed, since the reflection abstractions have been removed from v3.TestCaseBulkDeserializer
andTestCaseDescriptorFactory
have been removed, as the cross-Application Domain performance problems they were solving are no longer present in v3.TestClassException
has been removed, and replaced with a more generalizedTestPipelineException
.
Miscellaneous changes
In an effort to track down and eliminate cases of double enumeration, many method signatures may have changed from
IEnumerable<T>
toIReadOnlyCollection<T>
when it's known that the data is safe to double enumerate.BeforeAfterTestAttribute
is now given the instance ofIXunitTest
for the currently running test.DisposalTracker
has been switched fromIDisposable
toIAsyncDisposable
, and is capable of disposing of objects which implement either interface. Note that if an object implements both interfaces, onlyIAsyncDisposable
will be called.ExceptionUtility.ConvertExceptionToFailureInformation
has been replaced by.ExtractMetadata
, which returns the exception metadata as a tuple rather than an interface.IAsyncLifetime
has been updated to inherit fromIAsyncDisposable
, and bothDisposeAsync
andInitializeAsync
have been converted fromTask
toValueTask
.MemberDataAttributeBase.Parameters
has been renamed toArguments
to better align with the fact that it contains parameter argument values, not parameters.ConvertDataItem
has been renamed toConvertDataRow
(and now returns the newITheoryDataRow
object rather thanobject[]
). TheGetDataMethod
has been made async, and now returnsIReadOnlyCollection<ITheoryDataRow>
rather thanIEnumerable<object[]>
.Record.ExceptionAsync
has been updated to returnValueTask
as well as accepting lambdas that returnValueTask
.SerializationHelper.GetType
and.GetTypeNameForSerialization
have been replaced with.SerializedTypeNameToType
and.TypeToSerializedTypeName
, respectively. A non-generic version of.Deserialize
has been added, and the.Serialize
method now requires aType
to be passed in addition to the value.TheoryDataBase
is the new base type for theTheoryData<>
classes as well as the untypedTheoryData
.
Changes to Runner Utility
The runner utility libraries have had a fairly extensive overhaul. The two previous libraries (xunit.runner.reporters
and xunit.runner.utility
) were merged into a single library (xunit.v3.runner.utility
). Most of the types in this library have retained the Xunit
namespace, just like they previously had. Some sub-namespaces have been introduced to isolate code that's specific to running v1 vs. v2 vs. v3 tests.
A second new library (xunit.v3.runner.common
) was introduced. Types in this library primarily have the Xunit.Runner.Common
namespace.
The split between these two libraries comes from the fact that we now have an in-process console runner (that is the runner that is linked into your unit test projects, from the xunit.v3.runner.inproc.console
package) and an out-of-process console runner (the one in xunit.v3.runner.console
). The former only has to be able to run v3 test projects, whereas the latter has to be able to run projects from v1, v2, and v3.
The in-process console runner takes dependencies on xunit.v3.extensibility.core
and xunit.v3.runner.common
to be able to perform its runner duties, whereas xunit.v3.runner.utility
takes dependencies only on xunit.abstractions
to be able run v2 tests (and Mono.Cecil
to be able to read assembly metadata without loading the assembly into memory).
At the moment, third party reporters are not supported. We have an open issue to solve the problem of how to enable third party reporters without creating the strong dependency on xunit.v3.runner.utility
, as the strong dependency in v2 on xunit.runner.utility
made writing third party reporters exceptionally fragile.
Updated support for custom runner reporters
We have overhauled the way custom runner reporters are supported in v3. The new design for runner reporters directly links them into your test assembly, and the reporter is now chosen via the -reporter
switch (only available when you run your test project directly).
For more information, see the documentation page.
Namespace changes
The concrete test messages in the
Xunit
namespace (for example,DiagnosticMessage
) have moved to theXunit.Runner.Common
namespace. In the case where messages had non-empty constructors (for example,ErrorMessage
) they have been converted to a single parameterless constructor (for serialization/deserialization purposes), and helper static creation methods likeFromException
have been added to replace the previous constructor usage.The runner reporters (i.e.,
AppVeyorReporter
,DefaultRunnerReporter
, etc.) and their message handlers have moved fromXunit.Runner.Reporters
toXunit.Runner.Common
.AggregateMessageSink
has moved fromXunit
toXunit.Runner.Common
.AppDomainSupport
has moved fromXunit
toXunit.Runner.Common
.ConfigReader
,ConfigReader_Configuration
, andConfigReader_Json
have moved fromXunit
toXunit.Runner.Common
. TheLoad
method overloads that tookStream
have been removed.ConsoleRunnerLogger
has moved fromXunit
toXunit.Runner.Common
, and has been consolidated down to a single constructor that requires passing aConsoleHelper
object.DefaultTestCaseBulkDeserializer
andITestCaseBulkDeserializer
have moved fromXunit
toXunit.Internal
and are no longer directly supported for third party usage.DiagnosticEventSink
has moved fromXunit
toXunit.Runner.Common
.DiscoveryCompleteMessage
has been renamed toDiscoveryComplete
, and moved fromXunit
toXunit.Runner.Common
.DiscoveryEventSink
has moved fromXunit
toXunit.Runner.Common
.ExecutionEventSink
has moved fromXunit
toXunit.Runner.Common
.ExecutionSink
has moved fromXunit
toXunit.Runner.Common
.ExecutionSinkOptions
has moved fromXunit
toXunit.Runner.Common
.ExecutionSummary
has moved fromXunit
toXunit.Runner.Common
.IMessageSinkWithTypes
andIMessageSinkMessageWithTypes
have moved fromXunit
toXunit.Runner.v2
.IRunnerLogger
has moved fromXunit
toXunit.Runner.Common
.IRunnerReporter
has moved fromXunit
toXunit.Runner.Common
.IXunit1Executor
has moved fromXunit
toXunit.Runner.v1
.LongRunningTestsSummary
has moved fromXunit
toXunit.Runner.Common
.MessageHandler<T>
,MessageHandlerArgs
, andMessageHandlerArgs<T>
have moved fromXunit
toXunit.Runner.Common
.NullSourceInformationProvider
has moved fromXunit
toXunit.Runner.Common
.RunnerEventSink
has moved fromXunit
toXunit.Runner.Common
.RunnerReporterUtility
has moved fromXunit
toXunit.Runner.Common
, and now offers a way to directly retrieve just the embedded runner reporters.StackFrameInfo
andStackFrameTransformer
have moved fromXunit
toXunit.Runner.Common
.TestCaseDiscoveryMessage
has been renamed toTestCaseDiscovered
, and has moved fromXunit
toXunit.Runner.Common
.TestFrameworkOptions
has moved fromXunit
toXunit.Runner.Common
and now can be serialized.TransformFactory
has moved fromXunit.ConsoleClient
toXunit.Runner.Common
.Xunit1
,Xunit1Executor
,Xunit1RunSummary
, andXunit1TestCase
have moved fromXunit
toXunit.Runner.v1
and been updated for the new front controller contract.Xunit2
has moved fromXunit
toXunit.Runner.v2
and been updated for the new front controller contract.XunitFilters
has moved fromXunit
toXunit.Runner.Common
.XunitProject
andXunitProjectAssembly
have moved fromXunit
toXunit.Runner.Common
and been significantly restructured.
Types removed
DefaultTestCaseDescriptorProvider
has been removed.DelegatingExecutionSummarySink
,DelegatingFailSkipSink
,DelegatingLongRunningTestDetectionSink
,DelegatingXmlCreationSink
,FailSkipVisitor
,XmlAggregateVisitor
, andXmlTestExecutionVisitor
have been removed. They have been consolidated into a singleExecutionSink
class that ensures correct ordering behavior. Accordingly,IExecutionSink
andIExecutionVisitor
have also been removed.ITestCaseDescriptorProvider
andTestCaseDescriptor
have been removed.MessageSinkAdapter
andMessageSinkWithTypesAdapter
have been removed.TestDiscoveryVisitor
has been removed.TestMessageVisitor
andTestMessageVisitor<T>
have been removed.
Miscellaneous changes
AppVeyorClient
andVstsClient
have been moved frompublic
tointernal
.IFrontController
has hadCanUseAppDomains
removed, and has addedFindAndRun
andRun
methods to run tests. It has also been converted fromIDisposable
toIAsyncDisposable
.IFrontControllerDiscoverer
has been added, with aFind
method for finding tests (without running them), as well as exposing the metadata about the test project (including theCanUseAppDomains
property that was removed fromIFrontController
).ISourceInformationProvider.GetSourceInformation
has changed its return value fromISourceInformation
to(string? sourceFile, int? sourceLine)
.TestExecutionSummary
(for a single test assembly) has been replaced byTestExecutionSummaries
(for multiple test assemblies).XunitFrontController
has been updated for the new front controller contract, and is nowIAsyncDisposable
instead ofIDisposable
. Bulk deserializer and test descriptor functionality has been removed.