Welcome to Shouldly Documentation

A modern, assertion framework for .NET that focuses on clear error messages and fluent assertions

Current version: 4.2.1 (Released: April 2025)

Introduction

What is Shouldly?

Shouldly is a modern assertion framework for .NET that reimagines how test assertions should work. Unlike traditional assertion libraries, Shouldly focuses on providing exceptionally readable test code and human-friendly error messages that clearly show what went wrong. Its expressive syntax lets developers write assertions that read like natural language, making tests more intuitive and maintainable.

Traditional vs Shouldly Approach

Traditional Assertion
Assert.That(contestant.Points, Is.EqualTo(1337));

Error message:

Expected 1337 but was 0
Shouldly Assertion
contestant.Points.ShouldBe(1337);

Error message:

contestant.Points should be 1337 but was 0

Why use Shouldly?

Shouldly dramatically improves the testing experience by:

  • Providing highly descriptive error messages that include the actual code being tested
  • Using natural language assertions that improve readability and maintainability
  • Making tests more approachable for developers of all experience levels
  • Reducing the cognitive load needed to understand test failures
  • Seamlessly integrating with existing test frameworks like NUnit, xUnit, and MSTest

Key Features of Shouldly

Human-Readable Assertions

Write tests that read like sentences with methods like ShouldBe(), ShouldContain(), and ShouldThrow()

Exceptional Error Messages

Get detailed failure messages that include the actual code expression being tested

Fluent Syntax

Chain assertion methods naturally for complex verifications

Strongly-Typed

Enjoy full IntelliSense support and compile-time checking

Customizable

Extend with your own custom assertions when needed

Performance

Optimized for speed with minimal overhead compared to traditional assertions

Getting Started with Shouldly

Installation

Shouldly can be installed via NuGet package manager:

Install-Package Shouldly
nuget install Shouldly
dotnet add package Shouldly
View NuGet Package

Basic Usage Examples

using Shouldly;
using NUnit.Framework;

[Test]
public void BasicAssertionExamples()
{
    // Basic equality
    var myValue = 42;
    myValue.ShouldBe(42);
    
    // String operations
    string name = "John Smith";
    name.ShouldContain("Smith");
    name.ShouldStartWith("John");
    name.ShouldNotBeNullOrEmpty();
    
    // Collection assertions
    var myList = new[] { new Person { Name = "John" }, new Person { Name = "Jane" } };
    myList.ShouldContain(x => x.Name == "John");
    myList.ShouldNotBeEmpty();
    myList.Length.ShouldBe(2);
    
    // Exception testing
    Should.Throw(() => ThrowIfNegative(-1));
}

Advanced Usage

Shouldly provides numerous advanced assertions for more complex scenarios:

Working with Collections

// Collection assertions
var numbers = new[] { 1, 2, 3, 4, 5 };

numbers.ShouldContain(3);
numbers.ShouldNotContain(10);
numbers.ShouldBeSubsetOf(new[] { 1, 2, 3, 4, 5, 6, 7 });
numbers.ShouldAllBe(x => x > 0);
numbers.ShouldContain(x => x % 2 == 0);

Verifying Exceptions

// Exception assertions
Should.Throw(() => 
    ThrowException("Invalid argument"))
    .Message.ShouldContain("Invalid");

Should.NotThrow(() => DoSomethingThatShouldNotThrow());

// Exception with specific message
Should.Throw(() => 
    ThrowException("Parameter cannot be null"), 
    "Parameter cannot be null");

Working with Approximate Values

// Approximate comparisons for floating-point
double value = 0.1 + 0.2;  // 0.30000000000000004 in most systems
value.ShouldBe(0.3, 0.00001);

// Date assertions within a time range
DateTime now = DateTime.Now;
now.ShouldBeInRange(DateTime.Now.AddMinutes(-1), DateTime.Now.AddMinutes(1));

Real-World Examples

Unit Testing Example

This example demonstrates testing a shopping cart calculation service:

[Test]
public void CalculateTotal_WithValidItems_ReturnsCorrectTotal()
{
    // Arrange
    var cart = new ShoppingCart();
    cart.AddItem(new CartItem("Book", 10.99m, 2));
    cart.AddItem(new CartItem("Pen", 1.99m, 5));
    
    var service = new CartCalculationService();
    
    // Act
    decimal total = service.CalculateTotal(cart);
    
    // Assert
    total.ShouldBe(31.93m);
    cart.ItemCount.ShouldBe(2);
    cart.TotalItems.ShouldBe(7);
}

TDD Workflow Example

Using Shouldly in a Test-Driven Development approach:

// Step 1: Write failing test
[Test]
public void ValidateEmail_WithValidEmail_ReturnsTrue()
{
    // Arrange
    var validator = new EmailValidator();
    string email = "user@example.com";
    
    // Act
    bool isValid = validator.ValidateEmail(email);
    
    // Assert
    isValid.ShouldBeTrue();
}

// Step 2: Implement the simplest code to pass
public class EmailValidator
{
    public bool ValidateEmail(string email)
    {
        return email.Contains("@") && email.Contains(".");
    }
}

// Step 3: Add more tests for edge cases
[Test]
public void ValidateEmail_WithMissingAtSymbol_ReturnsFalse()
{
    // Arrange
    var validator = new EmailValidator();
    string email = "userexample.com";
    
    // Act
    bool isValid = validator.ValidateEmail(email);
    
    // Assert
    isValid.ShouldBeFalse();
}

Integration Testing Example

Using Shouldly to verify database operations:

[Test]
public async Task CreateUser_WithValidData_ShouldPersistToDatabase()
{
    // Arrange
    var repository = new UserRepository(_dbContext);
    var user = new User
    {
        Username = "johndoe",
        Email = "john@example.com",
        FirstName = "John",
        LastName = "Doe"
    };
    
    // Act
    await repository.CreateAsync(user);
    var savedUser = await repository.GetByIdAsync(user.Id);
    
    // Assert
    savedUser.ShouldNotBeNull();
    savedUser.Id.ShouldNotBe(0);
    savedUser.Username.ShouldBe("johndoe");
    savedUser.Email.ShouldBe("john@example.com");
    
    // Verify database was updated
    _dbContext.Users.Count().ShouldBe(1);
}

Resources for Shouldly

Official Documentation

Comprehensive guides and API reference for using Shouldly effectively in your testing projects.

View Documentation

GitHub Repository

The official source code repository where you can explore the codebase, report issues, or contribute to the project.

View on GitHub

Testing .NET Core with Shouldly

A detailed guide on implementing Shouldly in modern .NET Core applications with practical examples.

Read Guide

Shouldly vs Fluent Assertions

An in-depth analysis comparing Shouldly with its main competitor, helping you choose the right assertion framework for your project.

Read Comparison

Community and Support

Discussion Forum

Connect with other Shouldly users to ask questions and share best practices.

Join the Discussion

Stack Overflow

Browse through community questions and answers related to Shouldly implementation.

View Questions

Contributing

Guidelines for developers interested in contributing to the Shouldly project.

Learn How

What Developers Say

Comparison with Other Assertion Frameworks

Framework Syntax Style Error Messages Learning Curve .NET Support Last Update
Shouldly Natural language Detailed with code context Low Full .NET ecosystem April 2025
NUnit Traditional Basic Medium Full .NET ecosystem March 2025
xUnit Minimalist Basic Medium Full .NET ecosystem February 2025
Fluent Assertions Fluent chains Detailed Medium Full .NET ecosystem January 2025

Feature Comparison

Latest Updates and News

April 2025

Shouldly 4.2.1 Released

The latest point release brings performance improvements and bugfixes for async assertions.

Read Release Notes
March 2025

Shouldly 4.2.0 Released

Major update with new assertion methods and improved error messages for collection comparisons.

Read Release Notes
February 2025

The State of .NET Testing in 2025

Microsoft's developer blog covering the evolution of testing frameworks including Shouldly's growing adoption.

Read Article