Today, we're shipping three new releases:
It's been 2 months since the release of v2 2.5.0 RTM.
The introduction of the new assertion library in 2.5.0 (along with issues associated with the new package signing system used by .NET Foundation) necessitated this fairly quick point release. Most of what's been done for 2.5.1 is cleaning up issues discovered as people moved from 2.4.x to 2.5.0, some of which ended being showstopping issues. Hopefully we have resolved them all. 🤞
Users reported sporadic problems restoring the version 2.5.0 NuGet packages. As noted above, this is a result of .NET Foundation's code signing system changing the default time stamp server from DigiCert to Microsoft, which is not supported on .NET SDK 6.0.3xx (which is associated with Visual Studio 2022 LTS release 17.2). Users who were trying to stick with purely LTS builds of tools experienced NU3003 ("The package signature is invalid or cannot be verified on this platform."). We have since reverted back to the DigiCert time stamp service, which will allow users relying on LTS tooling to be able to restore our packages again.
As always, we'd like to thank all the users who contributed to the success of xUnit.net through usage, feedback, and code contributions. 🎉
These release notes are a comprehensive list of changes from 2.5.0 to 2.5.1.
[MemberData]
against a method with optional parameters (where you don't specify the values) is
not supported in v2. We have added a message alerting you to this, where previously we would just fail to find
a matching method.
xunit/xunit#1985
SerializationHelper
public. This class can be used to perform the serialization
that we normally use in xunit.runner.visualstudio
. This code is shared on both sides of the
system, so it's available as Xunit.SerializationHelper
in xunit.runner.utility.*
for runner authors, and Xunit.Sdk.SerializationHelper
in xunit.execution.*
for
extensibility authors. Note that the code is slightly different in that the execution version supports
assemblies marked with PlatformSpecificAssemblyAttribute
to transform their assembly
names in types to include the {Platform}
tag as appropriate. (This is behavior that only
applies to the execution side, and only for v2 tests.) This class can serialize any type that is supported
by xUnit.net's built-in serialization, which includes:
char
string
byte
and sbyte
short
and ushort
int
and uint
long
and ulong
float
and double
decimal
bool
DateTime
, DateTimeOffset
, and TimeSpan
BigInteger
(.NET Core only)Type
IXunitSerializable
BitArray
class has been marked as "safe to re-enumerate", so when it is printed in error messages
and/or theory data, it will show the bit values (as an array of True
and False
) rather
than the placeholder [···]
.
Assert.RaisesAny
and Assert.RaisesAnyAsync
to support
event handlers which return raw EventArgs
. This overload is non-generic (the generic overloads
are still used to obtain specific event data types). The need for this overload comes from the fact
that the delegate types for EventHandler
and EventHandler<T>
are not
compatible, so a non-generic version was required. These are the Any
variants because they
support events which return EventArgs
or any type that is derived from it; if you want
strong typing, you should follow up the Assert.RaisesAny
or Assert.RaisesAnyAsync
with an assertion like Assert.IsType
for the specific type you want to verify.
xunit/xunit#2773
xunit.assert.source
NuGet package to include a .editorconfig
file
that marks all files in the package as "auto-generated" so that they will be skipped for source analysis.
Previously, they would end up running against the analyzer rules for the importing project, and frequently
run afoul of things like not matching the desired coding style and formatting rules.
Assert.NotNull<T>()
overload designed for nullable value types.
xunit/xunit#2750
Assert.Equal
with dictionaries where the TValue
was a collection class (like an array or List<T>
).
xunit/xunit#2755
Assert.Equal
with HashSet
values, where the
internal comparer (passed during construction of the HashSet
) and/or the external comparer (passed
to Assert.Equal
) was not being used, causing false positives or negatives. Part of the implementation
of this fix also resolves a potential issue (never reported) with internal type AssertEqualityComparerAdapter
and an implementation of GetHashCode
that was throwing; it now correctly delegates to the instance
of IEqualityComparer<T>
that it is wrapping.
xunit/xunit#2743
Assert.Equivalent
with some tuple values where the comparison
was failing, even when the values should've been equivalent. This involved rewriting some sketchy logic related to
IComparable
which had previously been added just to support DateTime
and DateTimeOffset
;
now, instead, we explicitly handle those two types and never try to use IComparable
. This is more in line
with the originally intended purpose of Assert.Equivalent
, but it may now surface as unexpected false
negatives if any developers were relying on us calling their IComparable
implementation. The new logic is
the correct intention, and developers should not assume that we will use IComparable
(or any other
similar interface) for Assert.Equivalent
. Note that this does not affect our implementation
of Assert.Equal
, which still consults several equality-testing interfaces.
xunit/xunit#2758
CollectionTracker
.
The collection tracker was attempting to use its enumerator after it had been disposed, which manifested
in this particular case as a stray NullReferenceException
with Assert.Single
using a string of 5 characters of fewer, but in reality caused unexpected behavior depending on the
specific enumerator implementation. This could impact any assertion that inspected a collection.
xunit/xunit#2762
FileInfo
and DirectoryInfo
were
causing a stack overflow in Assert.Equivalent
, because they create an endless loop of objects
in their hierarchy (through the Root
property of DirectoryInfo
). There were
two fixes added:
FileSystemInfo
, the base class for FileInfo
and
DirectoryInfo
. When two of these are compared against each other, they only compare
the value of the FullName
property. Analysis shows that every other property is in
some way derived from the item on disk (whether it's a file or a directory), so comparing the
full names should be a good test of equivalency.
Assert.Equivalent
. If you try to
compare two instances of these classes with Assert.Equal
, they will show up as not equal,
because they are reference types which don't implement any of the equality interfaces in .NET that
you would normally expect/need when comparing equality.
xunit/xunit#2767
Assert.Equivalent
when comparing two values
which derive from FileSystemInfo
but weren't the same concrete type. This comparison now
just outright fails for mismatched types.
AssertHelper
when imported via xunit.assert.source
with .NET Standard 1.2 - 1.6 (complaining about the unavailability of the AppDomain
type).