Core Framework v2 2.5.1 2024 September 17
Today, we're shipping three new releases:
- xUnit.net Core Framework v2
2.5.1
- xUnit.net Analyzers 1.3.0 (release notes)
- xUnit.net Visual Studio adapter 2.5.1 (release notes)
It's been 2 months since the release of 2.5.0
.
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. 🤞
Important
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. 🎉
Release Notes
These release notes are a comprehensive list of changes from 2.5.0
to 2.5.1
.
Core Framework
Using
[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#1985We have made
SerializationHelper
public. This class can be used to perform the serialization that we normally use inxunit.runner.visualstudio
. This code is shared on both sides of the system, so it's available asXunit.SerializationHelper
inxunit.runner.utility.*
for runner authors, andXunit.Sdk.SerializationHelper
inxunit.execution.*
for extensibility authors. Note that the code is slightly different in that the execution version supports assemblies marked withPlatformSpecificAssemblyAttribute
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
andsbyte
short
andushort
int
anduint
long
andulong
float
anddouble
decimal
bool
DateTime
,DateTimeOffset
, andTimeSpan
BigInteger
(.NET Core only)Type
- Enums (not in the GAC)
- Types which implement
IXunitSerializable
- Arrays which contain values of supported types
Assertion Library
The
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 ofTrue
andFalse
) rather than the placeholder[···]
.Added an overload of
Assert.RaisesAny
andAssert.RaisesAnyAsync
to support event handlers which return rawEventArgs
. 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 forEventHandler
andEventHandler<T>
are not compatible, so a non-generic version was required. These are theAny
variants because they support events which returnEventArgs
or any type that is derived from it; if you want strong typing, you should follow up theAssert.RaisesAny
orAssert.RaisesAnyAsync
with an assertion likeAssert.IsType
for the specific type you want to verify. xunit/xunit#2773Updated the
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.BUG: Fixed an issue where proper nullable annotations were accidentally left off of the new
Assert.NotNull<T>()
overload designed for nullable value types. xunit/xunit#2750BUG: Fixed a regression in
Assert.Equal
with dictionaries where theTValue
was a collection class (like an array orList<T>
). xunit/xunit#2755BUG: Fixed an issue with
Assert.Equal
withHashSet
values, where the internal comparer (passed during construction of theHashSet
) and/or the external comparer (passed toAssert.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 typeAssertEqualityComparerAdapter
and an implementation ofGetHashCode
that was throwing; it now correctly delegates to the instance ofIEqualityComparer<T>
that it is wrapping. xunit/xunit#2743BUG: Fixed an issue with
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 toIComparable
which had previously been added just to supportDateTime
andDateTimeOffset
; now, instead, we explicitly handle those two types and never try to useIComparable
. This is more in line with the originally intended purpose ofAssert.Equivalent
, but it may now surface as unexpected false negatives if any developers were relying on us calling theirIComparable
implementation. The new logic is the correct intention, and developers should not assume that we will useIComparable
(or any other similar interface) forAssert.Equivalent
. Note that this does not affect our implementation ofAssert.Equal
, which still consults several equality-testing interfaces. xunit/xunit#2758BUG: Fixed an issue with improper disposal of enumerators by
CollectionTracker
. The collection tracker was attempting to use its enumerator after it had been disposed, which manifested in this particular case as a strayNullReferenceException
withAssert.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#2762BUG: Fixed an issue where
FileInfo
andDirectoryInfo
were causing a stack overflow inAssert.Equivalent
, because they create an endless loop of objects in their hierarchy (through theRoot
property ofDirectoryInfo
). There were two fixes added:We now set a maximum object traversal depth of 50, which is a number much higher than we assume anybody would be realistically testing against. If you exceed this, it throws an exception which tells you the path it followed to get to level 50, and suggests that you might have an infinite loop in your object hierarchy. This should prevent us from crashing with a stack overflow if there are any future situations like this (whether they come from built-in types or your own custom classes).
We special cased
FileSystemInfo
, the base class forFileInfo
andDirectoryInfo
. When two of these are compared against each other, they only compare the value of theFullName
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.
It's important to note that these fixes only apply to
Assert.Equivalent
. If you try to compare two instances of these classes withAssert.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#2767BUG: Fixed an issue with
Assert.Equivalent
when comparing two values which derive fromFileSystemInfo
but weren't the same concrete type. This comparison now just outright fails for mismatched types.BUG: Fixed an issue with
AssertHelper
when imported viaxunit.assert.source
with .NET Standard 1.2 - 1.6 (complaining about the unavailability of theAppDomain
type).
Extensibility
- BUG: Fixed an issue where the factory methods in the assert library's exception classes were not all properly marked as public as intended. xunit/xunit#2741