Table of Contents

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#1985

  • We have made 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
    • Enums (not in the GAC)
    • Types which implement IXunitSerializable
    • Arrays which contain values of supported types

    xunit/xunit#2770

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 of True and False) rather than the placeholder [···].

  • Added an overload of 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

  • Updated 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#2750

  • BUG: Fixed a regression in Assert.Equal with dictionaries where the TValue was a collection class (like an array or List<T>). xunit/xunit#2755

  • BUG: Fixed an issue with 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

  • BUG: 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 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

  • BUG: 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 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

  • BUG: Fixed an issue where 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:

    1. 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).

    2. We special cased 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.

    It's important to note that these fixes only apply to 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

  • BUG: Fixed an issue with 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.

  • BUG: Fixed an issue with AssertHelper when imported via xunit.assert.source with .NET Standard 1.2 - 1.6 (complaining about the unavailability of the AppDomain 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