Introduction To Property-Based Testing in C#

Written by miguel-bernard | Published 2020/07/01
Tech Story Tags: testing | programming | dotnet | tdd | property-based-testing | csharp | coding | code-quality | web-monetization

TLDR In this series, we'll go through all the steps to solve the Diamond Kata using TDD and property-based tests. We'll use FsCheck, a F# testing framework made for F#, to implement our first test in C#. The next post will show how to use the F# library to solve a specific Kata: print a diamond starting with A and having the supplied letter at the widest point. The first few tests are trivial, but as you approach Z, the tests are becoming harder to read and harder to write.via the TL;DR App

Intro

So far, we've talked about the benefits of property-based tests in my two previous blog posts here and here. I'm sure for most of you; this concept is still pretty abstract. We've seen the technique, but how do we implement it in C#? In this series, we'll go through all the steps to solve the Diamond Kata using TDD and property-based tests.
The Diamond Kata
Given an input letter, print a diamond starting with A and having the supplied letter at the widest point.
e.g., For input: D
---A---
--B-B--
-C---C-
D-----D
-C---C-
--B-B--
---A---
Why did I choose this specific Kata? Well, if you try to solve it with example-based tests, you effectively need 26 tests to make sure it works properly. It may not seem like a lot of tests, but if you try it, you'll soon discover that the first few tests are trivial, and as you approach Z, the tests are becoming harder to read and harder to write. It's usually a code smell that indicates that some property-based tests would be a better approach.
TDD
In this series, we'll also use TDD, and you'll see that it's much easier to use with Property-based tests than example-based tests. So in excellent TDD practitioners that we are, we are going to start with the most straightforward implementation of the algorithm that we can think of.
public class Diamond
{
    private static IEnumerable<string> Generate(char c)
    {
        yield return "A";
    }
}
Easy, right? It only works for the A case, but it's a good starting point.
I already hear the purists among you.
This is not the right way to do TDD! Red -> Green -> Refactor! You should start with a failing test, not with the implementation.
You are not wrong, but let's be realistic here. It's just a starting point, and I promise we'll do better TDD going forward :D.
The tools
Property-based tests is a simple enough concept, but generating proper pseudo-random inputs can be harder than it looks. Fortunately for us, other people solved that issue and built great tools. In our case, we'll use FsCheck, a property-based testing framework made for F#.
I'm confused, are we doing this in C# or F#?
That's the beauty of .NET, even though the library is made for F#, all the .NET languages compile to Intermediate Language (IL or MSIL) and thus are interoperable. It means we can call that library from C#.
Install the NuGet packages, and you are ready to go.
dotnet add package FsCheck --version 2.14.2
dotnet add package FsCheck.Xunit --version 2.14.2
Closing word
I think we have all the prerequisites to get started. Stay tuned for the next post where we'll implement our first test.

Written by miguel-bernard | Miguel is passionate about teaching, developers' communities and everything related to .Net.
Published by HackerNoon on 2020/07/01