Write Readable Tests with Fluent Assertions

This is part of my series on Automated Testing (for the .NET Developer). If you haven’t checked out the previous posts, you can do so with the links below:

In this (short) post, we’ll look at a tool that helps in writing human readable tests. While we place great emphasis on writing succint, non-duplicating operational code, when constructing test code, the focus is more so on the human readability of the code. Your automated testing suite should serve as a living, breathing, up-to-date documentation for your code. It makes your codebase approachable by allowing a developer to quickly get up-to-speed as to how the software behaves by looking at the tests.

There is a whole class of tooling dedicated to this. In the .NET space, some of these are Fluent Assertions (which we’ll look at in this post), Shouldly and Testify. In general, they provide a fluent syntax that mimics the English language. Personally, I have used Fluent Assertions and I find it to do a decent job

Fluent Assertion Examples

// See https://aka.ms/new-console-template for more information
using FluentAssertions;

// Strings
var username = "spiderman";
username.Should().NotBeNull();
username.Length.Should().BeGreaterThan(5).And.BeLessThan(15);

var password = "Peter#P4rk3r";
var confirmPassword = "Peter#P4rk3r";
confirmPassword.Should().BeSameAs(password);

// Dates
var dateOfBirth = new DateTime(1981, 06, 15);
dateOfBirth.Should().BeBefore(new DateTime().AddYears(-18));

var dateOfDeath = new DateTime(2020, 05, 12);
dateOfDeath.Should().BeAfter(dateOfBirth);

// Numbers
var age = 21;
age.Should().BePositive().And.BeLessThan(120);

// Collections
List<string> todoList = new List<string>();
todoList.Add("Get Milk");
todoList.Add("Get Break");
todoList.Add("Do taxes");

todoList.Should().NotBeEmpty().And.HaveCount(3, "because we added three items to the list.");
todoList.Should().NotContainNulls();

// Booleans
var toThyOwnSelf = true;
toThyOwnSelf.Should().BeTrue();

// Exceptions
Action doingBadStuff = () => {
    throw new InvalidOperationException("Don't do that!");
};

doingBadStuff.Should().Throw<InvalidOperationException>("because we told it to throw that exception when doing bad stuff");

Hopefully, you’ll agree that the statements above are easy to follow as a human reader. They are intention revealing and that’s important when writing and reading tests. So, go check them out.. Or check out one of the other ones I I listed. Pick one that you like and start using them in your tests. Happy coding and happy testing!

Leave a Comment

Your email address will not be published. Required fields are marked *