leebyron / testcheck-js

Generative testing for JavaScript

Home Page:http://leebyron.com/testcheck-js

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Mutable generated values are sometimes reused while shrinking

Zalathar opened this issue · comments

Open a console at http://leebyron.com/testcheck-js/api (or equivalent). Run this program and inspect the result, and compare out.result with out.shrunk.result.

out = check(
  property(
    gen.posInt.then(x => ({ x })).then(c => gen.object({ c, unused: gen.int })).then(({ c }) => c ),
    c => {
      if (c.used) throw new Error('used');
      c.used = true;
      return (c.x === 0);
    }
  )
)

Expected behaviour: The test finds a failing case, and then shrinks it to a smaller case that finds the same failure. Thus out.result === out.shrunk.result === false.

Actual behaviour: The test finds a failing case, tries to shrink it, but reuses the existing c that has already been mutated by a previous run. This changes the result, because the precondition fails and an exception is thrown instead. Thus out.result !== out.shrunk.result.

In practice this means that once a test fails, shrinking can result in misleading error messages, because the shrink tests are run against input that has already been mutated by previous tests.