migrate-xunit-to-xunit-v3
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
Chinesexunit.v3 Migration
xunit.v3 迁移指南
Migrate .NET test projects from xUnit.net v2 to xUnit.net v3. The outcome is a solution where all test projects reference packages, compiles cleanly, and all tests pass with the same results as before migration.
xunit.v3.*将.NET测试项目从xUnit.net v2迁移至xUnit.net v3。迁移完成后,解决方案中的所有测试项目将引用包,可正常编译,且所有测试的运行结果与迁移前一致。
xunit.v3.*When to Use
适用场景
- Upgrading test projects from (v2) packages to
xunitxunit.v3 - Resolving compilation errors after updating xunit package references to v3
- 将测试项目从(v2)包升级至
xunitxunit.v3 - 更新xUnit包引用至v3后解决编译错误
When Not to Use
不适用场景
- Migrating between test frameworks (e.g., MSTest or NUnit to xUnit.net) — different effort entirely
- Migrating from VSTest to Microsoft.Testing.Platform — use
migrate-vstest-to-mtp - The projects already reference — migration is done
xunit.v3
- 跨测试框架迁移(例如从MSTest或NUnit迁移到xUnit.net)——这完全是不同的工作内容
- 从VSTest迁移到Microsoft.Testing.Platform——请使用工具
migrate-vstest-to-mtp - 项目已引用——迁移已完成
xunit.v3
Inputs
输入项
| Input | Required | Description |
|---|---|---|
| Test project or solution | Yes | The .NET project or solution containing xUnit.net v2 test projects |
| 输入项 | 是否必填 | 描述 |
|---|---|---|
| 测试项目或解决方案 | 是 | 包含xUnit.net v2测试项目的.NET项目或解决方案 |
Workflow
工作流程
Commit strategy: Commit after each major step so the migration is reviewable and bisectable. Separate project file changes from code changes.
Prioritization: Steps 1-5 are required for every migration. Steps 6-12 are conditional — only apply the ones relevant to the project's code patterns. Skip steps that don't apply.
提交策略: 完成每个主要步骤后进行提交,确保迁移过程可审核、可二分排查。将项目文件变更与代码变更分开提交。
优先级说明: 步骤1-5是所有迁移都必须执行的。步骤6-12为可选步骤——仅应用与项目代码模式相关的步骤,跳过不适用的步骤。
Step 1: Identify xUnit.net projects and verify compatibility
步骤1:识别xUnit.net项目并验证兼容性
Search for test projects referencing xUnit.net v2 packages:
xunitxunit.abstractionsxunit.assertxunit.corexunit.extensibility.corexunit.extensibility.executionxunit.runner.visualstudio
Make sure to check the package references in project files, MSBuild props and targets files, like , , and .
Directory.Build.propsDirectory.Build.targetsDirectory.Packages.propsVerify target framework compatibility: xUnit.net v3 requires .NET 8+ or .NET Framework 4.7.2+. For test library projects, .NET Standard 2.0 is also supported. If any test projects have non-compatible target frameworks, STOP here — tell the user to upgrade the target framework first. Also verify the project uses SDK-style format.
搜索引用xUnit.net v2包的测试项目:
xunitxunit.abstractionsxunit.assertxunit.corexunit.extensibility.corexunit.extensibility.executionxunit.runner.visualstudio
请务必检查项目文件、MSBuild属性和目标文件中的包引用,例如、和。
Directory.Build.propsDirectory.Build.targetsDirectory.Packages.props验证目标框架兼容性:xUnit.net v3要求** .NET 8+ 或 .NET Framework 4.7.2+ **。对于测试库项目,也支持.NET Standard 2.0。如果任何测试项目使用不兼容的目标框架,请在此处停止——告知用户先升级目标框架。同时验证项目是否采用SDK风格格式。
Step 2: Update package references
步骤2:更新包引用
-
Update anyor
PackageReferenceitems for the new package names, based on the following mapping:PackageVersion- →
xunitxunit.v3 - → Remove entirely
xunit.abstractions - →
xunit.assertxunit.v3.assert - →
xunit.corexunit.v3.core - and
xunit.extensibility.core→xunit.extensibility.execution(if both are referenced in a project consolidate to only a single entry as the two packages are merged)xunit.v3.extensibility.core
-
Update allpackages to the latest correct version available on NuGet. Also update
xunit.v3.*to the latest version.xunit.runner.visualstudio
-
根据以下映射关系,更新所有或
PackageReference项至新包名:PackageVersion- →
xunitxunit.v3 - → 完全移除
xunit.abstractions - →
xunit.assertxunit.v3.assert - →
xunit.corexunit.v3.core - 和
xunit.extensibility.core→xunit.extensibility.execution(如果项目同时引用了这两个包,合并为单个引用即可,因为这两个包已合并)xunit.v3.extensibility.core
-
将所有包更新至NuGet上可用的最新正确版本。同时将
xunit.v3.*更新至最新版本。xunit.runner.visualstudio
Step 3: Set OutputType
to Exe
OutputTypeExe步骤3:设置OutputType
为Exe
OutputTypeExeIn each test project (excluding test library projects), set to in the project file:
OutputTypeExexml
<PropertyGroup>
<OutputType>Exe</OutputType>
</PropertyGroup>Depending on the solution in hand, there might be a centralized place where this can be added. For example:
- If all test projects share (or can share) a common , add the
Directory.Build.propsproperty there. Note that the OutputType should not be added to<OutputType>Exe</OutputType>.Directory.Build.targets - If all test projects share a name pattern (e.g., ), add a conditional property group in
*.Tests.csprojthat applies only to those projects, likeDirectory.Build.props. Adjust the condition as needed to target only test projects.<OutputType Condition="$(MSBuildProjectName.EndsWith('.Tests'))">Exe</OutputType> - Otherwise, add the property to each test project file individually.
<OutputType>Exe</OutputType>
在每个测试项目(测试库项目除外)的项目文件中,将设置为:
OutputTypeExexml
<PropertyGroup>
<OutputType>Exe</OutputType>
</PropertyGroup>根据手头的解决方案,可能存在可集中添加该配置的位置。例如:
- 如果所有测试项目共享(或可共享)一个通用的,则在其中的无条件
Directory.Build.props下添加PropertyGroup属性。注意不要将OutputType添加到<OutputType>Exe</OutputType>中。Directory.Build.targets - 如果所有测试项目都有统一的命名模式(例如),则在
*.Tests.csproj中添加一个条件属性组,仅应用于这些项目,例如Directory.Build.props。根据需要调整条件以仅针对测试项目。<OutputType Condition="$(MSBuildProjectName.EndsWith('.Tests'))">Exe</OutputType> - 否则,将属性单独添加到每个测试项目文件中。
<OutputType>Exe</OutputType>
Step 4: Configure test platform
步骤4:配置测试平台
Preserve the same test platform that was used with xUnit.net v2. xUnit.net v2 always uses VSTest except if the project used .
YTest.MTP.XUnit2- If the project had a reference to :
YTest.MTP.XUnit2- Remove the reference to completely.
YTest.MTP.XUnit2 - Add to
<UseMicrosoftTestingPlatformRunner>true</UseMicrosoftTestingPlatformRunner>under an unconditionalDirectory.Build.props.PropertyGroup
- Remove the reference to
- If the project did NOT reference (the common case):
YTest.MTP.XUnit2- Add to
<IsTestingPlatformApplication>false</IsTestingPlatformApplication>under an unconditionalDirectory.Build.props. IfPropertyGroupdoesn't exist, create it. This keeps the project on VSTest.Directory.Build.props
- Add
保留与xUnit.net v2相同的测试平台。xUnit.net v2始终使用VSTest,除非项目使用了。
YTest.MTP.XUnit2- 如果项目引用了:
YTest.MTP.XUnit2- 完全移除对的引用。
YTest.MTP.XUnit2 - 在的无条件
Directory.Build.props下添加PropertyGroup。<UseMicrosoftTestingPlatformRunner>true</UseMicrosoftTestingPlatformRunner>
- 完全移除对
- 如果项目未引用(常见情况):
YTest.MTP.XUnit2- 在的无条件
Directory.Build.props下添加PropertyGroup。如果<IsTestingPlatformApplication>false</IsTestingPlatformApplication>不存在,请创建它。这将使项目继续使用VSTest。Directory.Build.props
- 在
Step 5: Remove Xunit.Abstractions
usings
Xunit.Abstractions步骤5:移除Xunit.Abstractions
引用
Xunit.AbstractionsFind any directives in C# files and remove them completely.
using Xunit.Abstractions;查找C#文件中所有指令并完全移除。
using Xunit.Abstractions;Step 6: Address async void
breaking change (if applicable)
async void步骤6:处理async void
破坏性变更(如适用)
async voidIn xUnit.net v3, test methods are no longer supported and will fail to compile. Search for any test methods declared with and change them to . Test methods can be identified via the or attributes or other test attributes.
async voidasync voidasync Task[Fact][Theory]在xUnit.net v3中,测试方法不再被支持,且会编译失败。查找所有声明为的测试方法,并将其改为。可通过或属性或其他测试属性识别测试方法。
async voidasync voidasync Task[Fact][Theory]Step 7: Address breaking change of attributes (if applicable)
步骤7:处理属性的破坏性变更(如适用)
In xUnit.net v3, some attributes were updated so that they accept a instead of two strings (fully qualified type name and assembly name). These attributes are:
System.TypeCollectionBehaviorAttributeTestCaseOrdererAttributeTestCollectionOrdererAttributeTestFrameworkAttribute
For example, must be converted to .
[assembly: CollectionBehavior("MyNamespace.MyCollectionFactory", "MyAssembly")][assembly: CollectionBehavior(typeof(MyNamespace.MyCollectionFactory))]在xUnit.net v3中,部分属性已更新为接受类型参数,而非两个字符串(完全限定类型名和程序集名)。这些属性包括:
System.TypeCollectionBehaviorAttributeTestCaseOrdererAttributeTestCollectionOrdererAttributeTestFrameworkAttribute
例如,必须转换为。
[assembly: CollectionBehavior("MyNamespace.MyCollectionFactory", "MyAssembly")][assembly: CollectionBehavior(typeof(MyNamespace.MyCollectionFactory))]Step 8: Inheriting from FactAttribute or TheoryAttribute (if applicable)
步骤8:继承自FactAttribute或TheoryAttribute(如适用)
Identify if there are any custom attributes that inherit from or . These custom user-defined attributes must now provide source information. For example, if the attribute looked like this:
FactAttributeTheoryAttributecsharp
internal sealed class MyFactAttribute : FactAttribute
{
public MyFactAttribute()
{
}
}it must be changed to this:
csharp
internal sealed class MyFactAttribute : FactAttribute
{
public MyFactAttribute(
[CallerFilePath] string? sourceFilePath = null,
[CallerLineNumber] int sourceLineNumber = -1
) : base(sourceFilePath, sourceLineNumber)
{
}
}识别是否存在继承自或的自定义属性。这些用户自定义属性现在必须提供源信息。例如,如果原属性如下:
FactAttributeTheoryAttributecsharp
internal sealed class MyFactAttribute : FactAttribute
{
public MyFactAttribute()
{
}
}必须修改为:
csharp
internal sealed class MyFactAttribute : FactAttribute
{
public MyFactAttribute(
[CallerFilePath] string? sourceFilePath = null,
[CallerLineNumber] int sourceLineNumber = -1
) : base(sourceFilePath, sourceLineNumber)
{
}
}Step 9: Inheriting from BeforeAfterTestAttribute (if applicable)
步骤9:继承自BeforeAfterTestAttribute(如适用)
Identify if there are any custom attributes that inherit from . These custom user-defined attributes must update their method signatures. Previously, they would have / overrides that look like this:
BeforeAfterTestAttributeBeforeAftercsharp
public override void Before(MethodInfo methodUnderTest)
{
// Possibly some custom logic here
base.Before(methodUnderTest);
// Possibly some custom logic here
}
public override void After(MethodInfo methodUnderTest)
{
// Possibly some custom logic here
base.After(methodUnderTest);
// Possibly some custom logic here
}it must be changed to this:
csharp
public override void Before(MethodInfo methodUnderTest, IXunitTest test)
{
// Possibly some custom logic here
base.Before(methodUnderTest, test);
// Possibly some custom logic here
}
public override void After(MethodInfo methodUnderTest, IXunitTest test)
{
// Possibly some custom logic here
base.After(methodUnderTest, test);
// Possibly some custom logic here
}识别是否存在继承自的自定义属性。这些用户自定义属性必须更新其方法签名。之前的/重写方法如下:
BeforeAfterTestAttributeBeforeAftercsharp
public override void Before(MethodInfo methodUnderTest)
{
// 可能包含自定义逻辑
base.Before(methodUnderTest);
// 可能包含自定义逻辑
}
public override void After(MethodInfo methodUnderTest)
{
// 可能包含自定义逻辑
base.After(methodUnderTest);
// 可能包含自定义逻辑
}必须修改为:
csharp
public override void Before(MethodInfo methodUnderTest, IXunitTest test)
{
// 可能包含自定义逻辑
base.Before(methodUnderTest, test);
// 可能包含自定义逻辑
}
public override void After(MethodInfo methodUnderTest, IXunitTest test)
{
// 可能包含自定义逻辑
base.After(methodUnderTest, test);
// 可能包含自定义逻辑
}Step 10: Address new xUnit analyzer warnings (if applicable)
步骤10:处理新的xUnit分析器警告(如适用)
xunit.v3 introduced new analyzer warnings. The most notable is xUnit1051 (use for methods accepting ). Address these if present.
TestContext.Current.CancellationTokenCancellationTokenxunit.v3引入了新的分析器警告。最值得注意的是xUnit1051(为接受的方法使用)。如果存在此类警告,请进行处理。
CancellationTokenTestContext.Current.CancellationTokenStep 11: Migrate Xunit.SkippableFact
(if applicable)
Xunit.SkippableFact步骤11:迁移Xunit.SkippableFact
(如适用)
Xunit.SkippableFactIf there are any package references to , remove all these package references entirely.
Xunit.SkippableFactThen, follow these steps to eliminate usages of APIs coming from the removed package reference:
- Update any attribute to the regular
SkippableFactattribute.Fact - Update any attribute to the regular
SkippableTheoryattribute.Theory - Change method calls to
Skip.If.Assert.SkipWhen - Change method calls to
Skip.IfNot.Assert.SkipUnless
如果项目引用了包,请完全移除所有此类包引用。
Xunit.SkippableFact然后按照以下步骤消除已移除包引用的API用法:
- 将所有属性更新为常规
SkippableFact属性。Fact - 将所有属性更新为常规
SkippableTheory属性。Theory - 将方法调用改为
Skip.If。Assert.SkipWhen - 将方法调用改为
Skip.IfNot。Assert.SkipUnless
Step 12: Update companion packages (if applicable)
步骤12:更新配套包(如适用)
- 1.x → latest 2.x
Xunit.Combinatorial - 1.x → latest 3.x
Xunit.StaFact
- 1.x → 最新2.x版本
Xunit.Combinatorial - 1.x → 最新3.x版本
Xunit.StaFact
Step 13: Build and verify
步骤13:构建并验证
Build the solution and fix any remaining compilation errors. Run to verify all tests pass with the same results as before migration.
dotnet test构建解决方案并修复所有剩余的编译错误。运行以验证所有测试的运行结果与迁移前一致。
dotnet test