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:
- Part 1: An Introduction to Automated Testing
- Part 2: Frameworks & Tools for Automated Testing in the .NET Ecosystem
- Part 3: Your First Unit Test in xUnit
- Part 4: Further Explorations in xUnit
- Part 5: Unit Testing – What Should I Test?
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!