Faithlife.Testing 2.1.8

Prefix Reserved
dotnet add package Faithlife.Testing --version 2.1.8
                    
NuGet\Install-Package Faithlife.Testing -Version 2.1.8
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Faithlife.Testing" Version="2.1.8" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Faithlife.Testing" Version="2.1.8" />
                    
Directory.Packages.props
<PackageReference Include="Faithlife.Testing" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Faithlife.Testing --version 2.1.8
                    
#r "nuget: Faithlife.Testing, 2.1.8"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Faithlife.Testing@2.1.8
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Faithlife.Testing&version=2.1.8
                    
Install as a Cake Addin
#tool nuget:?package=Faithlife.Testing&version=2.1.8
                    
Install as a Cake Tool

Faithlife.Testing

NuGet

Faithlife.Testing uses the power of C# expression trees to help pinpoint exactly why your assertions are failing.

Table of Contents

Endorsements

"AssertEx is such a blessing, [...] it feels like a whole new world of possibilities has opened up to me."

- Joseph Stewart

"My mind was blown the first time I tried out a failure with AssertEx in linqpad."

- Ryan Johnson

"Oh, wow. That's amazing."

- Patrick Nausha, upon learning how AssertEx handles boolean logic

Why use Faithlife.Testing?

Some of the main problems that Faithlife.Testing is attempting to solve is:

  • The requirement to learn a new "syntax" when using a new test runner or assertion library.
string actual = "ab";
Assert.That(actual, Is.Not.Null.And.Length.AtLeast(3));
  • Many assertion libraries have common pits of failure, like using something like Assert.True. You're never going to get a helpful failure message out of an assertion like that.
bool isFrobbable = false;
Assert.True(isFrobbable);
...
Expected: True
But was: False
  • Needing to write "guard" assertions to get helpful failure messages. If you have a deeply nested object you want to assert on, you'd normally want to assert every property along the way isn't null, which can become quite tedious:
Assert.NotNull(foo);
Assert.NotNull(foo.Bar);
Assert.NotNull(foo.Bar.Baz);
  • Having many assertions fail, but only seeing one failure-message. When multiple things fail, you want to see all the failures -- but no more than that.
var foo = new Foo
{
    Name = "name",
    Id = 1,
    Bar = null,
 }
 Assert.AreEqual("test", foo.Name);
 Assert.AreEqual(1, foo.Id);
 Assert.NotNull(foo.Bar.Baz);

With Faithlife.Testing, those problems go away!

  • No learning a new syntax beyond calling AssertEx.IsTrue and AssertEx.HasValue, simply use C#!
string actual = "ab";
AssertEx.IsTrue(() => actual.Length >= 3);
...
Expected:
   actual.Length >= 3

Actual:
   actual.Length = 2
  • No more checking boolean expression against IsTrue! Just run the boolean expression.
bool isFrobbable = false;
AssertEx.IsTrue(() => isFrobbable);
...
Expected:
   isFrobbable

Actual:
   isFrobbable = false
  • There's no longer a need to use guard assertions so that you can know which property in a chain was the one that null.
var foo = new Foo
{
   Bar = null
};
AssertEx.HasValue(() => foo.Bar.Baz);
...
Expected:
   foo.Bar.Baz != null

Actual:
  foo.Bar = null
  • AssertEx will deconstruct boolean logic to show exactly why each assertion failed, and will elide the branches which did not fail.
var foo = new Foo
{
   Name = "name",
   Id = 1,
   Bar = null,
}
AssertEx.IsTrue(() => foo.Name == "test" && foo.Id == 1 && foo.Bar.Baz != null);
...
Expected:
   foo.Name == "test" && foo.Bar.Baz != null

Actual:
   foo.Name = "name"
   foo.Bar = null

Advanced Examples

A common pattern in testing is to have methods for fetching data whose callers then assertions on it. Faithlife.Testing exposes tools for preserving helpful context that a single method alone often lack.

Assertable<T>

Assertable<T> allows methods to return values on which further assertions can be made.

Context

Helpful context -- in the form of name/value pairs displayed in assertion messages -- can be attached to an Assertable<T>, and can also be attached to all assertions made inside a using block.

WaitUntil

AssertEx.WaitUntil allows you to retry a function which fetches a value until all assertions chained on it pass.

Limitations of Expressions

Because Faithlife.Testing is based around expressions, some newer C# language features cannot be used inside assertions. These features can be used inside functions called by your expression -- just not inside the expression itself.

These features include:

  • async/await - instead of using async/await in an expression, you can call a separate function to get an asynchronous value then make synchronous assertions on it.
  • The null-coalescing operator -- instead of using the null-coalescing ?. operator, just let the NullReferenceExceptions fly! Faithlife.Testing will tell you exactly what was null. Use the null-forgiving operator (!) as needed to avoid compiler warnings.
  • Modern pattern matching, e.g. is null, is not null, is "foo" or "bar", is { Year: 2023, Month: 8, Day: 24 }, etc.
Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (2)

Showing the top 2 NuGet packages that depend on Faithlife.Testing:

Package Downloads
Faithlife.Testing.RabbitMq

Test helpers for RabbitMQ-based integrations.

Faithlife.Testing.WebRequests

Faithlife.Testing.WebRequests class library.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
2.1.8 0 5/27/2026
2.1.7 115,358 6/9/2023
2.1.6 1,440 5/25/2023
2.1.5 6,478 10/7/2021
2.1.4 835 10/5/2021
2.1.3 843 10/5/2021
2.1.2 931 10/5/2021
2.1.1 879 10/4/2021
2.1.0 911 10/1/2021
2.0.1 9,138 6/16/2021
2.0.0 10,302 5/25/2021
1.3.0 1,184 11/10/2020
1.2.0 862 10/30/2020
1.1.0 888 10/28/2020
1.0.0 838 10/16/2020