question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Deriving one generated value from the other

See original GitHub issue

I’ve situation where for the property I need a list of integers and then a random index within the list. The property is something like this:

fun (nums: int list) (numIndex: int ) -> nums.Length > 1 && numIndex > 0 && numIndex < nums.Length ==> fun() -> ... // test property

numIndex is generated randomly without any ties to nums. Property test takes a long time and fails. I switched to generating the value in my test property:

fun (nums: int list) -> nums.Length > 1 ==> fun() ->
  let numIndex = Gen.choose (1, nums.Length - 1) |> Gen.sample 1 10 |> List.head
   ... // test property

That looks wrong and ugly. How can I customize for the numIndex to be generated based on the nums length to be passed to the property?

I tried to come up with custom generator, but couldn’t figure it all out. Thank you for your help.

Issue Analytics

  • State:closed
  • Created 7 years ago
  • Comments:6 (3 by maintainers)

github_iconTop GitHub Comments

2reactions
ploehcommented, Aug 16, 2016

You can use Arb.fromGenShrink instead. This enables you to supply your own shrinker.

Here’s an example that only shrinks numIndex:

[<Fact>]
let ShrinkDemo () =
    let shrinker (nums, numIndex) = 
        Arb.from<int>.Shrinker numIndex |> Seq.map (fun i -> nums, i)
    let g = 
        gen {
            let! nums = Gen.nonEmptyListOf Arb.generate<int>
            let! numIndex = Gen.choose (0, nums.Length - 1)
            return nums, numIndex }
    Arb.fromGenShrink (g, shrinker)
    |> Prop.forAll <| fun (nums, numIndex) -> numIndex < 11
    |> Check.QuickThrowOnFailure

Here, I’ve deliberately defined a property that I expect to fail, and true enough, here’s a typical test output:

Test 'ShrinkDemo' failed: System.Exception : Falsifiable, after 23 tests (1 shrink) (StdGen (1282257444,296192951)):
Original:
([7; 12; -3; -22; 2; 20; 8; -20; -24; 14; 2; 23; 19; 8; -4; 17; 13; -15], 12)
Shrunk:
([7; 12; -3; -22; 2; 20; 8; -20; -24; 14; 2; 23; 19; 8; -4; 17; 13; -15], 11)

    at <StartupCode$FsCheck>.$Runner.get_throwingRunner@365-1.Invoke(String message)
    at <StartupCode$FsCheck>.$Runner.get_throwingRunner@355.FsCheck-IRunner-OnFinished(String , TestResult )
    at FsCheck.Runner.check[a](Config config, a p)
    at FsCheck.Check.QuickThrowOnFailure[Testable](Testable property)
    C:\Users\mark\Documents\Library1.fs(36,0): at ShrinkDemo()

0 passed, 1 failed, 0 skipped, took 0,92 seconds (xUnit.net 2.1.0 build 3179).

That said, I find that I rarely need the shrunk values. FsCheck usually starts its generator with ‘small’ values, and it’ll stop as soon as it encounters a falsifiable result. Because of this ‘start small’ strategy, the falsifying input is often small enough that I understand what the problem is.

In an older Stack Overflow answer, @kurtschelfthout hints at the same experience:

Always start with the generator, then shrinker comes later if (when) you need it.

That answer is a few years old, though, so he may have changed his mind since then. If so, I’ll be happy to stand corrected.

0reactions
slavcommented, Aug 16, 2016

Thank you for the examples!

Read more comments on GitHub >

github_iconTop Results From Across the Web

JPA Derived Column value based on Identity column
Is there a better way of computing a derived column where the value depends on the generated Id ? Without the above hack...
Read more >
An Overview of Identifiers in Hibernate/JPA
In this example, we override the generate() method from the IdentifierGenerator interface. First, we want to find the highest number from the ...
Read more >
Auto Generated Values
Explains the different strategies for generating auto values (mainly for primary key fields) in JPA.
Read more >
GeneratedValue (Java(TM) EE 7 Specification APIs)
Provides for the specification of generation strategies for the values of primary keys. The GeneratedValue annotation may be applied to a primary key ......
Read more >
Derived Queries with Spring Data JPA – The Ultimate Guide
Spring Data JPA generates simple queries based on the name of a method in your repository. Your method names just have to follow...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found