Monthly Archives: September 2024

Custom generators for property-based tests in C#/.NET (CsCheck)

Here’s how you can create a custom generator for your property-based test in C# using CsCheck.

Example domain object

Assume we need to generate instances of this class:

class MyClass
{
    public int MyInt { get; set; }
    public string MyString { get; set; }
}

Building the custom generator

For the sake of this example, assume the generated instances must conform to these rules:

  1. The integer must be greater than 0.
  2. The string must be one of these: x, ✓, A string with 10 to 20 random characters.

Here’s what the generator looks like:

class MyGenerator
{
    public static Gen<MyClass> MyClass =>
        from i in Gen.Int where i > 0 
        from s in Gen.OneOf(Gen.String[10, 20], 
            Gen.Const("x"), 
            Gen.Const("✓"))
        select new MyClass
        {
            MyInt = i,
            MyString = s,
        };
}

Validating generated inputs

Here’s how to use it:

    [Fact]
    public void EachInputMustBeCorrect()
    {
        MyGenerator.MyClass.List.Sample(input =>
        {
            if(input.Count == 0) { return; }
            input.Should().AllSatisfy(MustBeCorrect);
        });
    }

    void MustBeCorrect(MyClass o)
    {
        o.MyInt.Should().BeGreaterThan(0);
        o.MyString.Should().Match(x => x == "x"  || 
            x == "✓" || 
            (x.Length >= 10 && x.Length <= 20)
        );
    }