Skip to content

Property based testing #2279

Open
Open

Description

@jpuriol

I believe it would be beneficial to add property-based tests to some of the exercises. This would ensure that students provide correct answers even for unusual edge cases. Have you considered this approach? I've already added property-based tests to the circular buffer exercise but am unsure how to contribute further.

Activity

  1. github-actions commented on Jun 26, 2024

    @github-actions
    Contributor

    Hello. Thanks for opening an issue on Exercism 🙂

    At Exercism we use our Community Forum, not GitHub issues, as the primary place for discussion. That allows maintainers and contributors from across Exercism's ecosystem to discuss your problems/ideas/suggestions without them having to subscribe to hundreds of repositories.

    This issue will be automatically closed. Please use this link to copy your GitHub Issue into a new topic on the forum, where we look forward to chatting with you!

    If you're interested in learning more about this auto-responder, please read this blog post.

  2. ErikSchierboom commented on Jun 26, 2024

    @ErikSchierboom
    Member

    We have two such exercises:

    • diamond
    • hyperia forex
  3. jpuriol commented on Jun 27, 2024

    @jpuriol
    Author

    Do you think these tests will improve the Circular Buffer exercise? I personally feel more confident about my implementation after running them, but I'm uncertain whether they cover more scenarios than the example-based tests. If you believe they add value, I can create a pull request to include them.

    [Property]
    public void WriteAndRead_ShouldWorkCorrectly(int capacity, int[] values)
    {
        if (capacity <= 0 || values == null) return;
    
        var buffer = new CircularBuffer<int>(capacity);
    
        foreach (var value in values)
        {
            buffer.Write(value);
            Assert.Equal(value, buffer.Read());
        }
    }
    
    [Property]
    public void WriteBeyondCapacity_ShouldThrowException(int capacity, int[] values)
    {
        if (capacity <= 0 || values == null) return;
    
        var buffer = new CircularBuffer<int>(capacity);
    
        foreach (var value in values)
        {
            if (buffer.Size < capacity)
            {
                buffer.Write(value);
            }
            else
            {
                Assert.Throws<InvalidOperationException>(() => buffer.Write(value));
            }
        }
    }
    
    [Property]
    public void ReadFromEmptyBuffer_ShouldThrowException(int capacity)
    {
        if (capacity <= 0) return;
    
        var buffer = new CircularBuffer<int>(capacity);
        Assert.Throws<InvalidOperationException>(() => buffer.Read());
    }
    
    [Property]
    public void Overwrite_ShouldReplaceOldestValue(int capacity, int[] values)
    {
        if (capacity <= 0 || values == null) return;
    
        var buffer = new CircularBuffer<int>(capacity);
    
        foreach (var value in values)
        {
            buffer.Overwrite(value);
        }
    
        for (int i = Math.Max(0, values.Length - capacity); i < values.Length; i++)
        {
            Assert.Equal(values[i], buffer.Read());
        }
    }
    
    [Property]
    public void Clear_ShouldResetBuffer(int capacity, int[] values)
    {
        if (capacity <= 0 || values == null) return;
    
        var buffer = new CircularBuffer<int>(capacity);
    
        foreach (var value in values)
        {
            if (buffer.Size < capacity)
            {
                buffer.Write(value);
            }
        }
    
        buffer.Clear();
        Assert.Throws<InvalidOperationException>(() => buffer.Read());
    }
  4. ErikSchierboom commented on Jul 9, 2024

    @ErikSchierboom
    Member

    Personally, I really like property-based tests, but in this case I think the existing test cases cover these scenarios well enough.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions