BurntSushi / quickcheck

Automated property based testing for Rust (with shrinking).
The Unlicense
2.4k stars 149 forks source link

Alternative to Arbitrary for testable things that cannot implement clone, etc? #169

Closed droundy closed 4 years ago

droundy commented 7 years ago

I have an object using arena allocation that I would love to be able to test using quickcheck. However, I cannot create an Arbitrary instance for it, because I cannot create a function that returns one, its lifetime must be tied to the lifetime of the allocator. And it certainly (easily?) can't be moved or cloned, since it is chock full of internal references (which is the point of using the allocator).

I'm not sure how I would create an arbitray-like behavior for this. If I were to reimplement quickcheck, there wouldn't be a particular problem, I would just pass in a new allocator for each call to arbitrary, and would hold that allocator until after running the test. But I don't see any way to achieve this with quickcheck itself.

Any suggestions? Is this just a use case in which quickcheck is unsuitable, or is there a way we could tweak quickcheck's API to handle such a scenario? It seems a bit like a corner case, but it also seems like you may most need tests for complicated data structures.

bluss commented 7 years ago

Wild speculation follows.

I suppose if we have a data structure X we can do this:

quickcheck! {
    fn test_x(seed: XSeed) -> bool {
          let a = Allocator::new();
          let x = seed.make_x(&a);
          /* body of property */
    }
}

Where XSeed is any kind of skeleton value that corresponds to a value x that can be given life with access to the allocator. Defining an XSeed skeleton might be tedious but it could be as simple as an RNG seed or a vector of them; that would be a delayed Arbitrary. Not necessarily easy to combine with shrinking, if it's just a literal RNG seed.

BurntSushi commented 4 years ago

I think @bluss's solution is probably as close as you can get. Not sure what else can be done.