Solving the diamond kata with property-based testing series
- How to get started with Property-based Testing in C#
- Input generators in property-based tests with FsCheck
- First and Last line content
- Height equals Width
- Outside space symmetry
- Symmetry around the vertical axis
- Symmetry around the horizontal axis
- No padding for input letter row
- Letters order
All code samples are available on github
Intro
Now that we have all the tools installed, we are finally ready to write our first Property-Based test.
FsCheck
Creating a property-based test is as simple as tagging a method with the [Property]
attribute, similarly as you would do in xUnit with the [Fact]
or [Theory]
attributes. If you dig a little, you will realize that there's a lot of configurable options on the [Property]
attribute. You can control how many random tests will be run each time, timeouts, etc. One of them is essential; the Arbitrary
property. That property will define which method to use to generate random inputs. In our specific case, we are not interested in all the possible values of char
. We only care about the 26 letters of the alphabet. To scope the input, we'll need to configure a generator that will do just that.
Generators
Generators are relatively simple.
- Create a static class
- Add a static method that returns
Arbitrary<TypeYouWantToGenerateValueFor>
- Voilà
You can write your randomization logic, but it's usually better to start from the built-in methods as they are already well balanced.
public static class LetterGenerator
{
public static Arbitrary<char> Generate() =>
Arb.Default.Char().Filter(c => c >= 'A' && c <= 'Z');
}
Not Empty Test
It may seem basic, but it's quite essential. We want to make sure we always have a non-empty result.
[Property(Arbitrary = new[] { typeof(LetterGenerator) })]
public Property NotEmpty(char c)
{
return Diamond.Generate(c).All(s => s != string.Empty).ToProperty();
}
One thing I forgot to mention earlier, the test method also needs to return a property
object. Fortunately for us, the library contains an extension method that can transform any boolean expression into a property object by calling ToProperty()
.
So our test reads like this:
- Call the Diamond.Generate() method with the provided input char
c
. - Make sure all the lines of the returned diamond are not empty.
- Use the
ToProperty()
method to wrap it into a property object.
Stay tuned
Stay tuned for my next posts on this series about solving the diamond kata with property-based testing. The following post will try to define properties for the first and last lines of our diamond.
Solving the diamond kata with property-based testing series
- How to get started with Property-based Testing in C#
- Input generators in property-based tests with FsCheck
- First and Last line content
- Height equals Width
- Outside space symmetry
- Symmetry around the vertical axis
- Symmetry around the horizontal axis
- No padding for input letter row
- Letters order
All code samples are available on github
Top comments (0)