Git Product home page Git Product logo

Comments (5)

kurtschelfthout avatar kurtschelfthout commented on June 5, 2024 1

Arrays/lists can have very long shrink sequences. It tries to remove one element at a time.

from fscheck.

kurtschelfthout avatar kurtschelfthout commented on June 5, 2024

FsCheck has no magic way to prevent shrinking if you literally evaluate it explicitly. Under normal circumstances, it won't shrink unless the random part of the test fails.

Shrinking can take a long time. It can also get stuck in a loop, if shrinking a value yields the same value again somewhere along the way.

from fscheck.

rynoV avatar rynoV commented on June 5, 2024

Sorry maybe I didn't explain well. I'm defining an arbitrary instance like

let arbInstance =
    { new Arbitrary<...>() with
        override x.Generator = ...

        override x.Shrinker(dates) = ...
        }

and the issue I'm having is that putting

let _ = (ArbMap.defaults |> ArbMap.arbitrary |> Arb.toShrink) dates |> Seq.length

inside my Shrinker method override freezes my tests, even when they're passing, in which case I would expect Shrinker to never be called.

I suppose it doesn't really matter, since the implementation shouldn't evaluate the infinite sequence anyways, it was just confusing behaviour and took me a while to figure out what was happening.

I'll make a PR adding to the docs that the sequence of shrinks may be infinite, and evaluating that sequence may freeze the tests even if no tests are failing.

from fscheck.

kurtschelfthout avatar kurtschelfthout commented on June 5, 2024

I see. Yes, FsCheck relies on the laziness of the returned sequence. It will call Shrinker during normal evaluation of the test, and capture the resulting sequence. This allows it to pick up shrinking with the values the test failed with. It effectively captures Shrinker(dates) in a closure, but only evaluates the resulting sequence one at a time, and only evaluates the sequence if the random test fails.

from fscheck.

rynoV avatar rynoV commented on June 5, 2024

Thanks for the explanation, I'll update my PR tomorrow.

I managed to minimize the issue I was running into, it turned out to be just that the shrink sequence was a lot bigger than I thought. A minimal repro:

    [<Property>]
    let ``test`` () =
        Prop.forAll (
            { new Arbitrary<int[]>() with
                override x.Generator = Seq.init 500 (fun i -> i) |> Seq.toArray |> Gen.constant

                override x.Shrinker(vs) =
                    let shrunk = (ArbMap.defaults |> ArbMap.arbitrary |> Arb.toShrink) vs
                    // let _ = Seq.length shrunk
                    Seq.empty }
        )
        <| fun (vs) -> true

Here, uncommenting the Seq.length line makes the test take 10 seconds. Commented it takes less than a second.

My original case was generating a datetime array with a size much larger than 500, so it appeared the test was stuck in an infinite loop.

from fscheck.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.