Source: kevintsengtw/dotnet-testing-agent-skills (MIT). Ported into dotnet-agent-harness.
xUnit Upgrade Guide: From 2.9.x to 3.x
Applicable Scenarios
Use this skill when asked to perform the following tasks:
- Upgrade existing xUnit 2.x test projects to xUnit 3.x
- Evaluate the scope of impact for xUnit upgrade
- Resolve compilation errors during xUnit upgrade
- Use xUnit 3.x new features to improve tests
Core Concepts
Package Naming Changes
xUnit v3 adopts a new package naming strategy:
| v1~v2 Package Name |
v3 Package Name |
Description |
xunit |
xunit.v3 |
Main test framework |
xunit.assert |
xunit.v3.assert |
Assertion library |
xunit.core |
xunit.v3.core |
Core components |
xunit.abstractions |
(removed) |
No longer needed |
xunit.runner.visualstudio |
xunit.runner.visualstudio (3.x.y) |
Test runner |
Important: Use xunit.v3 package name, not xunit.
Minimum Runtime Requirements
xUnit 3.x strict requirements:
- .NET Framework 4.7.2+ or
- .NET 8.0+ (recommended)
Unsupported versions:
- .NET Core 3.1
- .NET 5, 6, 7
Breaking Changes List
1. Test Project Becomes Executable
<!-- xUnit 2.x (Library) -->
<PropertyGroup>
<OutputType>Library</OutputType>
</PropertyGroup>
<!-- xUnit 3.x (Exe) - Must change -->
<PropertyGroup>
<OutputType>Exe</OutputType>
</PropertyGroup>
```text
### 2. async void Tests No Longer Supported
```csharp
// ❌ xUnit 2.x - fails in 3.x
[Fact]
public async void TestSomeAsyncFunction()
{
var result = await SomeAsyncMethod();
Assert.True(result);
}
// ✅ xUnit 3.x - correct way
[Fact]
public async Task TestSomeAsyncFunction()
{
var result = await SomeAsyncMethod();
Assert.True(result);
}
```text
### 3. IAsyncLifetime Changes
In xUnit 3.x, `IAsyncLifetime` inherits `IAsyncDisposable`. If implementing both `IAsyncLifetime` and `IDisposable`, only `DisposeAsync` will be called, not `Dispose`.
```csharp
// ⚠️ Pattern to note
public class MyTestClass : IAsyncLifetime, IDisposable
{
public async Task InitializeAsync() { /* ... */ }
public async Task DisposeAsync() { /* will be called */ }
public void Dispose() { /* will NOT be called in 3.x */ }
}
// ✅ Recommended: put all cleanup logic in DisposeAsync
public class MyTestClass : IAsyncLifetime
{
public async Task InitializeAsync() { /* initialization */ }
public async Task DisposeAsync() { /* all cleanup logic */ }
}
```text
### 4. SkippableFact/SkippableTheory Removed
```csharp
// ❌ xUnit 2.x - removed
[SkippableFact]
public void SkippableTest()
{
Skip.If(someCondition, "Skip reason");
// test logic
}
// ✅ xUnit 3.x - use Assert.Skip
[Fact]
public void SkippableTest()
{
if (someCondition)
{
Assert.Skip("Skip reason");
}
// test logic
}
```text
### 5. SDK-style Projects Only
Check if project file starts with:
```xml
<Project Sdk="Microsoft.NET.Sdk">
```text
If traditional format, must convert to SDK-style first.
---
## Upgrade Steps
### Step 1: Create Upgrade Branch
```bash
git checkout -b feature/upgrade-xunit-v3
```text
### Step 2: Update Project Files
```xml
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<OutputType>Exe</OutputType>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
<IsTestProject>true</IsTestProject>
</PropertyGroup>
<ItemGroup>
<!-- xUnit v3 packages -->
<PackageReference Include="xunit.v3" Version="3.0.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="3.1.4">
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.13.0" />
<!-- Common helper packages -->
<PackageReference Include="AwesomeAssertions" Version="8.1.0" />
<PackageReference Include="NSubstitute" Version="5.3.0" />
</ItemGroup>
</Project>
```text
### Step 3: Fix async void Tests
Use IDE search:
```regex
async\s+void.*\[(Fact|Theory)\]
```text
Change all `async void` to `async Task`.
### Step 4: Update using Statements
```csharp
// Remove (no longer needed)
// using Xunit.Abstractions;
// Keep
using Xunit;
```text
### Step 5: Compile and Test
```bash
dotnet clean
dotnet restore
dotnet build
dotnet test --verbosity normal
```text
---
## xUnit 3.x New Features
### Dynamic Skip Tests
**Declarative (SkipUnless/SkipWhen)**:
```csharp
[Fact(SkipUnless = nameof(IsWindowsEnvironment),
Skip = "This test only runs on Windows")]
public void OnlyRunOnWindowsTest()
{
// test logic
}
public static bool IsWindowsEnvironment =>
RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
```text
**Imperative (Assert.Skip)**:
```csharp
[Fact]
public void SkipBasedOnEnvironmentVariableTest()
{
var enableTests = Environment.GetEnvironmentVariable("ENABLE_INTEGRATION_TESTS");
if (string.IsNullOrEmpty(enableTests) || enableTests.ToLower() != "true")
{
Assert.Skip("Integration tests disabled. Set ENABLE_INTEGRATION_TESTS=true to run");
}
// test logic...
}
```text
### Explicit Tests
```csharp
[Fact(Explicit = true)]
public void ExpensiveIntegrationTest()
{
// This test won't run by default unless explicitly requested
// Suitable for performance tests, long-running tests
}
```text
### [Test] Attribute
```csharp
// All three ways have same functionality
[Test]
public void UsingTestAttributeTest() { Assert.True(true); }
[Fact]
public void UsingFactAttributeTest() { Assert.True(true); }
```text
### Matrix Theory Data
```csharp
public static TheoryData<int, string> TestData =>
new MatrixTheoryData<int, string>(
[1, 2, 3], // number data
["Hello", "World", "Test"] // string data
);
// This generates 3×3=9 test cases
[Theory]
[MemberData(nameof(TestData))]
public void MatrixTestExample(int number, string text)
{
number.Should().BePositive();
text.Should().NotBeNullOrEmpty();
}
```text
### Assembly Fixtures
```csharp
public class DatabaseAssemblyFixture : IAsyncLifetime
{
public string ConnectionString { get; private set; }
public async Task InitializeAsync()
{
// create test database
ConnectionString = await CreateTestDatabaseAsync();
}
public async Task DisposeAsync()
{
// cleanup test database
await DropTestDatabaseAsync();
}
}
// Register Assembly Fixture
[assembly: AssemblyFixture(typeof(DatabaseAssemblyFixture))]
// Use in tests
public class UserServiceTests
{
private readonly DatabaseAssemblyFixture _dbFixture;
public UserServiceTests(DatabaseAssemblyFixture dbFixture)
{
_dbFixture = dbFixture;
}
[Fact]
public void Test1() { /* use _dbFixture.ConnectionString */ }
}
```text
### Test Pipeline Startup
```csharp
public class TestPipelineStartup : ITestPipelineStartup
{
public async Task ConfigureAsync(ITestPipelineBuilder builder,
CancellationToken cancellationToken)
{
// global initialization logic
Console.WriteLine("Initializing test environment...");
await InitializeDatabaseAsync();
}
}
// Register
[assembly: TestPipelineStartup(typeof(TestPipelineStartup))]
```text
---
## xunit.runner.json Configuration
```json
{
"$schema": "https://xunit.net/schema/v3/xunit.runner.schema.json",
"parallelAlgorithm": "conservative",
"maxParallelThreads": 4,
"diagnosticMessages": true,
"internalDiagnosticMessages": false,
"methodDisplay": "classAndMethod",
"preEnumerateTheories": true,
"stopOnFail": false
}
```text
---
## Test Report Formats
xUnit 3.x supports multiple report formats:
```bash
# Generate CTRF format report
dotnet run -- -ctrf results.json
# Generate TRX format report
dotnet run -- -trx results.trx
# Generate XML format report
dotnet run -- -xml results.xml
# Generate multiple format reports
dotnet run -- -xml results.xml -ctrf results.json -trx results.trx
```text
---
## Common Issues and Solutions
### Issue 1: xunit.abstractions not found
**Error**: `The type or namespace name 'Abstractions' does not exist`
**Solution**: Remove `using Xunit.Abstractions;`, related types have moved to `Xunit` namespace.
### Issue 2: Custom DataAttribute not working
In xUnit 3.x `DataAttribute` method signature has changed: `GetData(MethodInfo)` -> `GetDataAsync(MethodInfo, DisposalTracker)`, return type changed to `Task<IReadOnlyCollection<ITheoryDataRow>>`.
### Issue 3: IDE cannot discover tests
Confirm IDE version meets requirements:
- Visual Studio 2022 17.8+
- Rider 2023.3+
- VS Code (latest)
If still issues, temporarily disable Microsoft Testing Platform:
```xml
<PropertyGroup>
<EnableMicrosoftTestingPlatform>false</EnableMicrosoftTestingPlatform>
</PropertyGroup>
```text
---
## Upgrade Checklist
### Before Upgrade
- [ ] Confirm target framework version (.NET 8+ or .NET Framework 4.7.2+)
- [ ] Check project file format (SDK-style)
- [ ] Identify all async void test methods
- [ ] Check IAsyncLifetime implementations
- [ ] Evaluate dependency package compatibility
- [ ] Create backup branch
### During Upgrade
- [ ] Update package references (use `xunit.v3`)
- [ ] Remove `xunit.abstractions` references
- [ ] Modify OutputType to Exe
- [ ] Fix all async void test methods
- [ ] Update using statements
- [ ] Refactor custom attributes (if any)
- [ ] Verify compilation success
- [ ] Run all tests
### Post-Upgrade Verification
- [ ] Functional completeness testing
- [ ] Performance benchmark comparison
- [ ] CI/CD Pipeline validation
- [ ] Documentation update
- [ ] Team training
---
## IDE and Tool Support
### IDE Version Requirements
| IDE | Minimum Version |
| --- | --------------- |
| Visual Studio | 2022 17.8+ |
| VS Code | Latest |
| Rider | 2023.3+ |
### Microsoft Testing Platform
xUnit 3.x enables Microsoft Testing Platform by default:
```xml
<PropertyGroup>
<EnableMicrosoftTestingPlatform>true</EnableMicrosoftTestingPlatform>
<OutputType>Exe</OutputType>
</PropertyGroup>
```text
---
## Performance Improvements
Performance improvements brought by xUnit 3.x:
1. **Independent process execution**: Tests run in separate processes, better isolation
2. **Improved parallel algorithm**: Smarter load balancing
3. **Faster startup time**: Executable runs directly
4. **Better memory isolation**: Reduced interference between tests
---
## Reference Resources
### Original Articles
This skill content is distilled from the "Old School Software Engineer's Testing Practice - 30 Day Challenge" article series:
- **Day 26 - xUnit Upgrade Guide: Transition from 2.9.x to 3.x**
- Article: https://ithelp.ithome.com.tw/articles/10377477
- Sample code: https://github.com/kevintsengtw/30Days_in_Testing_Samples/tree/main/day26
### Official Documentation
- [xUnit.net Official Website](https://xunit.net/)
- [xUnit v3 New Features Documentation](https://xunit.net/docs/getting-started/v3/whats-new)
- [xUnit 2.x -> 3.x Official Migration Guide](https://xunit.net/docs/getting-started/v3/migration)
- [xunit.v3 NuGet Package](https://www.nuget.org/packages/xunit.v3)
1---2name: dotnet-testing-advanced-xunit-upgrade-guide-33description: "Complete guide for upgrading xUnit 2.9.x to 3.x. Use when upgrading xUnit v2 to v3 or understanding xUnit v3 new features and breaking changes. Covers package updates, async void fixes, IAsyncLifetime adjustments. Includes new features: Assert.Skip, Explicit Tests, Matrix Theory, Assembly Fixtures. Keywords: xunit upgrade, xunit v3, xunit 3.x, xunit migration, xunit upgrade, xunit.v3, OutputType Exe, IAsyncLifetime v3, Assert.Skip, SkipUnless, SkipWhen, Explicit attribute, MatrixTheoryData, AssemblyFixture, breaking changes"4---5Source: kevintsengtw/dotnet-testing-agent-skills (MIT). Ported into dotnet-agent-harness.67# xUnit Upgrade Guide: From 2.9.x to 3.x89## Applicable Scenarios1011Use this skill when asked to perform the following tasks:1213- Upgrade existing xUnit 2.x test projects to xUnit 3.x14- Evaluate the scope of impact for xUnit upgrade15- Resolve compilation errors during xUnit upgrade16- Use xUnit 3.x new features to improve tests1718## Core Concepts1920### Package Naming Changes2122xUnit v3 adopts a new package naming strategy:2324| v1~v2 Package Name | v3 Package Name | Description |25| --------------------------- | ----------------------------------- | ------------------- |26| `xunit` | `xunit.v3` | Main test framework |27| `xunit.assert` | `xunit.v3.assert` | Assertion library |28| `xunit.core` | `xunit.v3.core` | Core components |29| `xunit.abstractions` | (removed) | No longer needed |30| `xunit.runner.visualstudio` | `xunit.runner.visualstudio` (3.x.y) | Test runner |3132**Important**: Use `xunit.v3` package name, not `xunit`.3334### Minimum Runtime Requirements3536xUnit 3.x strict requirements:3738- **.NET Framework 4.7.2+** or39- **.NET 8.0+** (recommended)4041**Unsupported versions**:4243- .NET Core 3.144- .NET 5, 6, 74546---4748## Breaking Changes List4950### 1. Test Project Becomes Executable5152````xml53<!-- xUnit 2.x (Library) -->54<PropertyGroup>55 <OutputType>Library</OutputType>56</PropertyGroup>5758<!-- xUnit 3.x (Exe) - Must change -->59<PropertyGroup>60 <OutputType>Exe</OutputType>61</PropertyGroup>62```text6364### 2. async void Tests No Longer Supported6566```csharp67// ❌ xUnit 2.x - fails in 3.x68[Fact]69public async void TestSomeAsyncFunction()70{71 var result = await SomeAsyncMethod();72 Assert.True(result);73}7475// ✅ xUnit 3.x - correct way76[Fact]77public async Task TestSomeAsyncFunction()78{79 var result = await SomeAsyncMethod();80 Assert.True(result);81}82```text8384### 3. IAsyncLifetime Changes8586In xUnit 3.x, `IAsyncLifetime` inherits `IAsyncDisposable`. If implementing both `IAsyncLifetime` and `IDisposable`, only `DisposeAsync` will be called, not `Dispose`.8788```csharp89// ⚠️ Pattern to note90public class MyTestClass : IAsyncLifetime, IDisposable91{92 public async Task InitializeAsync() { /* ... */ }93 public async Task DisposeAsync() { /* will be called */ }94 public void Dispose() { /* will NOT be called in 3.x */ }95}9697// ✅ Recommended: put all cleanup logic in DisposeAsync98public class MyTestClass : IAsyncLifetime99{100 public async Task InitializeAsync() { /* initialization */ }101 public async Task DisposeAsync() { /* all cleanup logic */ }102}103```text104105### 4. SkippableFact/SkippableTheory Removed106107```csharp108// ❌ xUnit 2.x - removed109[SkippableFact]110public void SkippableTest()111{112 Skip.If(someCondition, "Skip reason");113 // test logic114}115116// ✅ xUnit 3.x - use Assert.Skip117[Fact]118public void SkippableTest()119{120 if (someCondition)121 {122 Assert.Skip("Skip reason");123 }124 // test logic125}126```text127128### 5. SDK-style Projects Only129130Check if project file starts with:131132```xml133<Project Sdk="Microsoft.NET.Sdk">134```text135136If traditional format, must convert to SDK-style first.137138---139140## Upgrade Steps141142### Step 1: Create Upgrade Branch143144```bash145git checkout -b feature/upgrade-xunit-v3146```text147148### Step 2: Update Project Files149150```xml151<Project Sdk="Microsoft.NET.Sdk">152 <PropertyGroup>153 <TargetFramework>net8.0</TargetFramework>154 <OutputType>Exe</OutputType>155 <ImplicitUsings>enable</ImplicitUsings>156 <Nullable>enable</Nullable>157 <IsPackable>false</IsPackable>158 <IsTestProject>true</IsTestProject>159 </PropertyGroup>160161 <ItemGroup>162 <!-- xUnit v3 packages -->163 <PackageReference Include="xunit.v3" Version="3.0.1" />164 <PackageReference Include="xunit.runner.visualstudio" Version="3.1.4">165 <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>166 <PrivateAssets>all</PrivateAssets>167 </PackageReference>168 <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.13.0" />169170 <!-- Common helper packages -->171 <PackageReference Include="AwesomeAssertions" Version="8.1.0" />172 <PackageReference Include="NSubstitute" Version="5.3.0" />173 </ItemGroup>174</Project>175```text176177### Step 3: Fix async void Tests178179Use IDE search:180181```regex182async\s+void.*\[(Fact|Theory)\]183```text184185Change all `async void` to `async Task`.186187### Step 4: Update using Statements188189```csharp190// Remove (no longer needed)191// using Xunit.Abstractions;192193// Keep194using Xunit;195```text196197### Step 5: Compile and Test198199```bash200dotnet clean201dotnet restore202dotnet build203dotnet test --verbosity normal204```text205206---207208## xUnit 3.x New Features209210### Dynamic Skip Tests211212**Declarative (SkipUnless/SkipWhen)**:213214```csharp215[Fact(SkipUnless = nameof(IsWindowsEnvironment),216 Skip = "This test only runs on Windows")]217public void OnlyRunOnWindowsTest()218{219 // test logic220}221222public static bool IsWindowsEnvironment =>223 RuntimeInformation.IsOSPlatform(OSPlatform.Windows);224```text225226**Imperative (Assert.Skip)**:227228```csharp229[Fact]230public void SkipBasedOnEnvironmentVariableTest()231{232 var enableTests = Environment.GetEnvironmentVariable("ENABLE_INTEGRATION_TESTS");233234 if (string.IsNullOrEmpty(enableTests) || enableTests.ToLower() != "true")235 {236 Assert.Skip("Integration tests disabled. Set ENABLE_INTEGRATION_TESTS=true to run");237 }238239 // test logic...240}241```text242243### Explicit Tests244245```csharp246[Fact(Explicit = true)]247public void ExpensiveIntegrationTest()248{249 // This test won't run by default unless explicitly requested250 // Suitable for performance tests, long-running tests251}252```text253254### [Test] Attribute255256```csharp257// All three ways have same functionality258[Test]259public void UsingTestAttributeTest() { Assert.True(true); }260261[Fact]262public void UsingFactAttributeTest() { Assert.True(true); }263```text264265### Matrix Theory Data266267```csharp268public static TheoryData<int, string> TestData =>269 new MatrixTheoryData<int, string>(270 [1, 2, 3], // number data271 ["Hello", "World", "Test"] // string data272 );273 // This generates 3×3=9 test cases274275[Theory]276[MemberData(nameof(TestData))]277public void MatrixTestExample(int number, string text)278{279 number.Should().BePositive();280 text.Should().NotBeNullOrEmpty();281}282```text283284### Assembly Fixtures285286```csharp287public class DatabaseAssemblyFixture : IAsyncLifetime288{289 public string ConnectionString { get; private set; }290291 public async Task InitializeAsync()292 {293 // create test database294 ConnectionString = await CreateTestDatabaseAsync();295 }296297 public async Task DisposeAsync()298 {299 // cleanup test database300 await DropTestDatabaseAsync();301 }302}303304// Register Assembly Fixture305[assembly: AssemblyFixture(typeof(DatabaseAssemblyFixture))]306307// Use in tests308public class UserServiceTests309{310 private readonly DatabaseAssemblyFixture _dbFixture;311312 public UserServiceTests(DatabaseAssemblyFixture dbFixture)313 {314 _dbFixture = dbFixture;315 }316317 [Fact]318 public void Test1() { /* use _dbFixture.ConnectionString */ }319}320```text321322### Test Pipeline Startup323324```csharp325public class TestPipelineStartup : ITestPipelineStartup326{327 public async Task ConfigureAsync(ITestPipelineBuilder builder,328 CancellationToken cancellationToken)329 {330 // global initialization logic331 Console.WriteLine("Initializing test environment...");332 await InitializeDatabaseAsync();333 }334}335336// Register337[assembly: TestPipelineStartup(typeof(TestPipelineStartup))]338```text339340---341342## xunit.runner.json Configuration343344```json345{346 "$schema": "https://xunit.net/schema/v3/xunit.runner.schema.json",347 "parallelAlgorithm": "conservative",348 "maxParallelThreads": 4,349 "diagnosticMessages": true,350 "internalDiagnosticMessages": false,351 "methodDisplay": "classAndMethod",352 "preEnumerateTheories": true,353 "stopOnFail": false354}355```text356357---358359## Test Report Formats360361xUnit 3.x supports multiple report formats:362363```bash364# Generate CTRF format report365dotnet run -- -ctrf results.json366367# Generate TRX format report368dotnet run -- -trx results.trx369370# Generate XML format report371dotnet run -- -xml results.xml372373# Generate multiple format reports374dotnet run -- -xml results.xml -ctrf results.json -trx results.trx375```text376377---378379## Common Issues and Solutions380381### Issue 1: xunit.abstractions not found382383**Error**: `The type or namespace name 'Abstractions' does not exist`384385**Solution**: Remove `using Xunit.Abstractions;`, related types have moved to `Xunit` namespace.386387### Issue 2: Custom DataAttribute not working388389In xUnit 3.x `DataAttribute` method signature has changed: `GetData(MethodInfo)` -> `GetDataAsync(MethodInfo, DisposalTracker)`, return type changed to `Task<IReadOnlyCollection<ITheoryDataRow>>`.390391### Issue 3: IDE cannot discover tests392393Confirm IDE version meets requirements:394395- Visual Studio 2022 17.8+396- Rider 2023.3+397- VS Code (latest)398399If still issues, temporarily disable Microsoft Testing Platform:400401```xml402<PropertyGroup>403 <EnableMicrosoftTestingPlatform>false</EnableMicrosoftTestingPlatform>404</PropertyGroup>405```text406407---408409## Upgrade Checklist410411### Before Upgrade412413- [ ] Confirm target framework version (.NET 8+ or .NET Framework 4.7.2+)414- [ ] Check project file format (SDK-style)415- [ ] Identify all async void test methods416- [ ] Check IAsyncLifetime implementations417- [ ] Evaluate dependency package compatibility418- [ ] Create backup branch419420### During Upgrade421422- [ ] Update package references (use `xunit.v3`)423- [ ] Remove `xunit.abstractions` references424- [ ] Modify OutputType to Exe425- [ ] Fix all async void test methods426- [ ] Update using statements427- [ ] Refactor custom attributes (if any)428- [ ] Verify compilation success429- [ ] Run all tests430431### Post-Upgrade Verification432433- [ ] Functional completeness testing434- [ ] Performance benchmark comparison435- [ ] CI/CD Pipeline validation436- [ ] Documentation update437- [ ] Team training438439---440441## IDE and Tool Support442443### IDE Version Requirements444445| IDE | Minimum Version |446| --- | --------------- |447| Visual Studio | 2022 17.8+ |448| VS Code | Latest |449| Rider | 2023.3+ |450451### Microsoft Testing Platform452453xUnit 3.x enables Microsoft Testing Platform by default:454455```xml456<PropertyGroup>457 <EnableMicrosoftTestingPlatform>true</EnableMicrosoftTestingPlatform>458 <OutputType>Exe</OutputType>459</PropertyGroup>460```text461462---463464## Performance Improvements465466Performance improvements brought by xUnit 3.x:4674681. **Independent process execution**: Tests run in separate processes, better isolation4692. **Improved parallel algorithm**: Smarter load balancing4703. **Faster startup time**: Executable runs directly4714. **Better memory isolation**: Reduced interference between tests472473---474475## Reference Resources476477### Original Articles478479This skill content is distilled from the "Old School Software Engineer's Testing Practice - 30 Day Challenge" article series:480481- **Day 26 - xUnit Upgrade Guide: Transition from 2.9.x to 3.x**482 - Article: https://ithelp.ithome.com.tw/articles/10377477483 - Sample code: https://github.com/kevintsengtw/30Days_in_Testing_Samples/tree/main/day26484485### Official Documentation486487- [xUnit.net Official Website](https://xunit.net/)488- [xUnit v3 New Features Documentation](https://xunit.net/docs/getting-started/v3/whats-new)489- [xUnit 2.x -> 3.x Official Migration Guide](https://xunit.net/docs/getting-started/v3/migration)490- [xunit.v3 NuGet Package](https://www.nuget.org/packages/xunit.v3)491````