Today, we're shipping three new releases:
It's been 11 months since the release of 2.4.2 RTM.
Aside from normal quality of life improvements, the primary feature of this release is a heavily updated assertion library, which includes several new assertions, several new overloads for existing assertions, and a pass to ensure that the messages from the assertions are now more concise and consistent. We wrote up an overview of the updates in the 2.5.0 assertion library messages. For the most part, developers should not notice much compile-time differences (aside from perhaps the occasional type ambiguity that may come from new overloads); there are also some breaking binary changes, most prominently with the gutting and reworking of the exception classes that are thrown by the individual assertions. Because of some of these breaking changes, we felt it was warranted to bump the version up to 2.5.0.
This release removes all support for UWP from the core framework and VSTest adapter, based on Microsoft's deprecation of UWP in favor of WinUI 3 (and now MAUI). Users who need to continue to work with UWP will need to stay with the v2 2.4.2 core framework and 2.4.5 Visual Studio runner.
As always, we'd like to thank all the users who contributed to the success of xUnit.net through usage, feedback, and code contributions. 🎉
Note that we have moved away from Twitter for our occasional updates, and now make those available
on our Mastodon account:
You may follow along by creating a Mastodon account
and following our account, or via a news reader using the RSS feed.
These release notes are a comprehensive list of changes from 2.4.2 to 2.5.0.
TimeSpan(supported on all frameworks)
BigInteger(supported on all frameworks except .NET Framework)
DateOnly(supported on .NET 6 and later)
TimeOnly(supported on .NET 6 and later)
ExcludeFromCodeCoverageAttributeto all the xUnit.net assemblies. This should resolve issues with
dotnet test ---collect "Code Coverage"(the new cross-platform code coverage system) incorrectly showing coverage for xUnit.net itself. xunit/xunit#2682
Assert.IsNotAssignableFrom. It performs the opposite action of
Assert.Containsbehaved unexpectedly with dictionaries and sets. This is because these both have custom logic for their
Containsfunction that is contrary to our normal container comparison logic. Their constructors allow you to pass key comparers; normally, comparers are only used when looking things up. This fixes this so it will have consistent behavior with the framework. xunit/xunit#2671
Assert.Equal(DateTime, DateTime, TimeSpan)and
Assert.Equal(DateTimeOffset, DateTimeOffset, TimeSpan)overloads. They specify a precision (in time span) that the two times must be within one another. This precision works in both directions: expected earlier than actual, or expected later than actual. xunit/xunit#2588
Assert.Equal(T, T, Func<T, T, bool> comparer)and
Assert.NotEqual(T, T, Func<T, T, bool> comparer)overloads. This allows the dev to write an inline comparison function rather than being forced to implement one of the equality interfaces (like
IEqualityComparer<T>) in a separate class. xunit/xunit#2692
Assert.Equal()for strings has a new flag:
ignoreAllWhiteSpaceindicates that all whitespace should be ignored. The difference between this and
ignoreWhiteSpaceDifferencesis that the latter requires at least one piece of whitespace. Examples:
Assert.Equal("a b", "ab", ignoreWhiteSpaceDifferences: true);
Assert.Equal("a b", "ab", ignoreAllWhiteSpace: true);xunit/xunit#2440
Assert.Nulloverloads explicitly for
Nullable<T>struct values. Both include new messages, and the
NotNullvariant returns the unwrapped
Tvalue. This prevents boxing, and makes it trivial to use the non-null value. (We don't need this with the reference versions, since the type doesn't change, it just sheds its nullability, which we automatically do with the
Assert.DoesNotContainfor the concrete type
Assert.Equivalentwith two equal values that are of different (but compatible) types previously failed. After discussion with the community, this was fixed to now pass. Example of code that now passes that previously failed:
Assert.Equivalent(12, 12L);Poll on Mastodon
xunit.analyzers, causes compilation to report
xUnit2015warnings. These warnings aren't applicable to the assertion library itself, so they've been suppressed with pragmas. This means you should no longer need to ignore or disable those warnings when using
xunit.assert.source(or the Git submodule). xunit/xunit#2472
Assert.Throws<ArgumentException>()threw an exception when you passed a null parameter name, despite being legal in
Assert.Equivalentwas not appropriately handling reference types inside of value types. xunit/xunit#2431
Assert.Equivalentwas inadvertently comparing non-public properties. xunit/xunit#2621
Assert.Equivalentwas incorrectly trying to compare indexer properties (which are more like functions than properties). Now, this will skip indexer properties. xunit/xunit#2698
Assert.Equal(float, float, int precision)and
Assert.Equal(float, float, int precision, MidpointRounding). xunit/xunit#2393
IAssertionExceptionwas accidentally always public, even when importing via source and setting `XUNIT_VISIBILITY_INTERNAL`. xunit/xunit#2703
XunitExceptionwhich was breaking libraries like Fluent Assertions. xunit/xunit#2737
Func<ValueTask>was set for
ArgumentException, but should've been
xunit.console.x86.exe. New MSBuild parameters are available (when referencing the
xunit.runner.consoleNuGet package) which point to the console runner executable on disk:
failSkipsconfiguration element to convert skipped tests into failed tests. This aligns with the
-failSkipsconsole runner command line option and the
FailSkipsMSBuild runner property.
stopOnFailconfiguration file element in the console and MSBuild runners. This was documented as supported in the v2.3 schema, but complete support in all runners was not added until v2 2.5.
DiagnosticMessageclass now implements
ToString()and outputs the message, for simpler debugging for extensibility authors.
*reporters*.dllwhich may break any custom reporters you are using from first or third party assemblies without an appropriate name. xunit/visualstudio.xunit#317
CollectionTrackerpublic (in the assertion library). The former is used to pretty print values in assertion failures as well arguments for display names of data-driven tests. The latter is a newly introduced class whose job is to prevent double enumeration while tracking the last few values visited, so that they can be printed when assertion failures happen without requiring a second enumeration.
XUNIT_NULLABLEwas not defined, but your project had
<nullable>enable</nullable>. You should always define
xunit.assert.source(or the Git submodule) when you have nullable enabled, but at least now if you forget to do that, there won't be any compiler warnings as a result of you using our non-nullable path. Note that we had to use pragmas to disable warnings rather than just using
#nullable disablein the files, since that pragma didn't exist in C# prior to version 8 (and we set a minimum C# version of 6).
TestFrameworkOptions.ForExecutionto read the
stopOnFailconfiguration file element and propagate the setting into the execution options.
FactAttribute-derived class could cause tests to become inappropriately ignored due to an exception throw during discovery. Now, when a test method is decorated with a misbehaving attribute, the test will still be discovered, and when run it will fail with information about the failure. Unaffected tests in the same class will no longer be affected by this failure. xunit/xunit#2719