Today, we're shipping xUnit.net 2.4.2; this includes RTM builds of the core framework and analyzers (now at version 1.0.0! 🎉).
It's been nearly 4 years since the release of 2.4.1 RTM. This release includes a few targeted bug fixes for the core framework, and an updated assertion library with many of the new v3 assertions being back-ported to v2. This new assertion library includes several new assertions and overloads of existing assertions, improvements to output for failing tests, and nullable annotations.
We did not intend to ship any more v2 releases; that said, we also did not intend for the v3 development process to take as long as it has. We felt it was necessary to address a couple specific high-friction issues (including two from the .NET Team at Microsoft); the new assertions are merely an extra reason to encourage the upgrade (and help tide teams over who might be waiting for v3 with some of the new features).
You will notice that we have not changed any of the minimum requirements for this release, despite the fact that .NET 4.5.2 and .NET Core 1.0 are quite old at this point. We did not want to disrupt the workflow of those who may still be stuck on older (even out of support) versions of .NET Framework or .NET Core. You should not consider this an endorsement that you use these older versions of .NET Framework or .NET Core; this was merely about making as few changes as possible to minimize compatibility issues, especially with third party extensibility libraries and test runners. Please upgrade to supported versions as soon as possible, as some of them are not even receiving security patches at this point in time.
This need to stick to the older target frameworks is the reason we are unable
to ship the new assertions based on Span
, Memory
and
ValueTask
. If you wish you be able to consume these, they are part
of the source package xunit.assert.source
, which you could use
(instead of xunit.assert
), and then define the appropriate constants
in the project (using
<DefineConstants>
in your project file) to enable more advanced features. For more information on the
constants and available features, please see the
Assertion library
home page README.
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 reflect the entirety of the changes between 2.4.1 and 2.4.2.
Skip
on an
[InlineData]
attribute was being ignored by Visual Studio Test Explorer.
xunit/visualstudio.xunit#266
decimal
values weren't
usable in generic theories because the type coercion logic was not accounting for
the possibility of multiple type-compatible op_Implicit
or
op_Explicit
methods.
xunit/xunit#2418
null
(it
would incorrectly use object
to close all the generic types rather than
continuing to inspect the subsequent non-null
values for their
correct types).
xunit/xunit#2401
DisposalTracker
which was a race
condition that could cause objects to fail to get disposed and/or cause objects to
get disposed twice.
xunit/xunit#1855
Assert.Distinct
to verify that a collection does not contain any duplicate values.
xunit/assert.xunit#35
Assert.Equivalent
to check for object equivalence. Object equivalence
is intended to be a looser kind of assertion than Assert.Equal
. This assertion
allows an optional strict
flag to influence its behavior. The rules for equivalence
are as follows:
null
values are only ever equivalent to other null
values (regardless
of strict
).
strict
).
In particular, this means that types must match exactly (for example, int
and
long
values are never equivalent, even if they have the same underlying value; or,
in code form: Assert.Equivalent(12, 12L);
will fail).
[1, 2]
is equivalent to [2, 1]
) and
regardless of the collection type (for example, List<int>
can be compared
against int[]
). The strict
parameter influences this comparison by requiring
that all values in the expected
list are in the actual
list (meaning
expected: [1, 2]
is equivalent to actual: [2, 3, 1]
when strict
is false
, but not equivalent when strict
is true
). Another
way to think of this is that strict: false
allows actual
to be a strict
superset of expected
, whereas strict: true
does not.
strict
).
Circular references are not allowed, and will be surfaced as test failures. For all other reference types,
the public non-static fields and readable properties are compared for equivalence without regard to the
types of the two values and without regard to which values came from fields vs. properties.
Like collections, the strict
flag indicates whether actual
is allowed to be a
strict superset of expected
(strict: false
) or an exact match (strict:
true
). Reference types inspected in this way determine the equivalence of individual field/property
values by using these same sets of rules when comparing the field/property values. This includes reference
type values (meaning the reference type equivalence is considered to be "deep", not "shallow").
KeyValuePair<,>
is handled specially: the keys are checked for equivalence
against each other, as are the values; this allows embedded collections inside of keys and/or
values inside a KeyValuePair.
Assert.Fail
which unilaterally fails the test with the given message.
xunit/xunit#2105
Assert.Multiple
which allows the developer to run several independent
assertions (expressed as Action
s) and then collect up all the failures into
a single failure. This behavior differs from the default behavior (which stops running
assertions upon the first failure).
xunit/xunit#1920
Assert.All
which takes an Action<T, int>
so
the inspecting action get access to both the value and its index in the collection.
xunit/xunit#2082
Assert.Equal
for doubles which includes a MidpointRounding
flag.
xunit/xunit#2074
Assert.Equal
for floats and doubles that allows specifying a
tolerance (rather than a precision).
xunit/xunit#1293
xunit/xunit#1984
Assert.Collection
with a pointer-style message (like string
assertions) that make it easier to identify the failing part of the collection.
xunit/xunit#994
xunit/xunit#1924
Assert.Empty
to match other expected/actual exceptions.
xunit/xunit#1806
Assert.Single
to improve the output message when
being used with a "match" expression (it used to say the collection was empty, but
now correctly mentions the fact that you were matching specific values).
xunit/assert.xunit#28
Assert.Equal
for strings with ignoreWhiteSpace: true
.
xunit/xunit#1931
Assert.Equal
with collections that can iterate multiple times
(which is generally considered bad form with IEnumerable
). The most egregious case of
this was fixed, though there is still at least one more possibility during test failure to end
up enumerating a second time.
xunit/xunit#2402
Assert.NotNull
tells the compiler that the object
parameter will
not null
if the function doesn't throw. Assert.Null
similarly
tells the compiler that the object
parameter may be null
if
the function doesn't throw.
Assert.Contains
and Assert.DoesNotContain
for dictionaries requires
the dictionary key type to be non-nullable.
Assert.Single
against non-generic IEnumerable
indicates the return
value may be null
.
null
parameter values
are acceptable and when they aren't, as well as updating return signatures to indicate when
returned values may or may not be null
.
True
, False
, and Fail
) are marked as
never returning (aka, throwing) based on the input data.
XunitException
's constructors which take inner exceptions as public
.
xunit/assert.xunit#33
Assert.Raises
, Assert.RaisesAny
, and
Assert.RaisesAsync
) no longer express type requirements for EventArgs
.
xunit.runner.visualstudio
The xunit.runner.visualstudio
package has a separate lifecycle and
separate minimum framework requirements from xUnit.net core. Use this table
to determine which version you should use (pick the lowest version of
the combination of target frameworks you're using):
2.4.1 | 2.4.3 | 2.4.5 | |
---|---|---|---|
.NET Framework | 4.5.2 | 4.5.2 | 4.6.2 |
.NET Core | 1.0 | 2.1 | 3.1 |
UWP | 10.0.10240 | 10.0.16299 | 10.0.16299 |
Visual Studio does not allow mixed versions of this package in your solution, so do not mix versions; doing so may cause problems running your projects that need the older version of the runner package. Choose the lowest version of the package that applies to all of the test projects in your solution.