Skip to main content

Migration

aweXpect.Migration is a Roslyn analyzer that migrates assertions from FluentAssertions and xUnit to aweXpect. It reports each assertion of these libraries, and its code fix rewrites the call site to the aweXpect equivalent where it knows one.

Upgrading from an older aweXpect version instead? See the upgrade guides from aweXpect 2.x and from aweXpect 3.x.

Installation​

Install aweXpect (the assertion library you are migrating to) into the test project you want to migrate:

dotnet add package aweXpect

Latest version: 3.4.0

Then add aweXpect.Migration (the analyzers and code fixers) as a development dependency:

dotnet add package aweXpect.Migration

Latest version: 0.7.0

aweXpect.Migration ships only the analyzer and code fixer, no runtime code.

It is usually convenient to add the following global usings to the project so the rewritten code compiles without further edits:

global using System.Threading.Tasks;
global using aweXpect;

The code fix writes Expect.That(...). The hand-written examples under "Behavioral differences" use the shorter That(...) and assume global using static aweXpect.Expect; as well.

How it works​

After installing the package, every assertion of the source library is reported as a warning:

DiagnosticSource libraryCode fix title
aweXpectM002FluentAssertionsMigrate FluentAssertions to aweXpect
aweXpectM003xUnitMigrate xUnit assertion to aweXpect

aweXpectM002 is raised on every .Should() invocation defined under the FluentAssertions namespace (nested .Should() calls inside lambda arguments are intentionally skipped, so chains like .Should().AllSatisfy(x => x.Should().BeGreaterThan(0)) are migrated as a single unit). aweXpectM003 is raised on every method call on Xunit.Assert.

The code fix is offered only where the fixer knows a rewrite. An assertion without one, for example a chained call it does not recognize, keeps its warning and has to be migrated by hand.

A typical migration looks like this:

// Before
subject.Should().BeTrue();
Assert.Equal(expected, actual);

// After
await Expect.That(subject).IsTrue();
await Expect.That(actual).IsEqualTo(expected);

Expectations in aweXpect only run when they are awaited. The rewritten expressions are therefore awaited in a second step, which the aweXpect0001 analyzer that ships with aweXpect itself enforces and fixes.

In the IDE​

Apply "Fix all in solution" for aweXpectM002 and aweXpectM003 from your IDE (Visual Studio, Rider, VS Code with C# Dev Kit), then "Fix all" for aweXpect0001 to add the missing await and mark the surrounding methods async.

From the command line​

Migration is a two-pass operation: first apply the rewrites, then add the missing await and async keywords:

# 1. Rewrite assertions
dotnet format analyzers --diagnostics aweXpectM002 aweXpectM003 --severity warn

# 2. Add the missing `await` (and mark surrounding methods `async`)
dotnet format analyzers --diagnostics aweXpect0001 --severity warn

Supported assertions​

The rewrites for each source library, and the cases in which the migrated expectation behaves differently, are listed on separate pages:

Removing aweXpect.Migration again​

Once the warnings in a project have been resolved, drop the analyzer reference:

dotnet remove package aweXpect.Migration

aweXpect itself stays in the project; that is the assertion library the tests now depend on.