0

I am doing stateful testing using Jqwik. The problem I am facing is as follows:

The action chain contains a set of state dependent actions that can produce empty Arbitraries (example: no "pop" action should be produced for an empty stack). Some actions are state independent and are always "productive" (like "push" a value on the stack).

The issue is that action chains are generated randomly and sometimes only non-productive actions are selected which in turn produces empty chains and ends up in the net.jqwik.api.JqwikException: empty set of values.

Increasing weight on "productive" actions mitigates the issue but does not solve it.

Is there a way to make sure at least one "productive" action is always selected and hence the generated action chain is always non-empty?

I've tried to use ActionChain.independent() with endOfChain() transformer but it did not help.

  • 1
    That‘s the reason why actions can have preconditions. If you show your current action code, I might be able to give more concrete advice. – johanneslink Nov 01 '22 at 05:54
  • The example in jqwik's user guide seem to cover your exact question: https://jqwik.net/docs/current/user-guide.html#specifying-actions – johanneslink Nov 01 '22 at 11:03
  • Indeed, I've read about preconditions after I asked the question. However: in my case "state" is a database and precondition check should be performed in one step with Transformer generation (for example: retrieve a list of records from the db and generate Transformers with Arbitrary.of(records).map(...)). Current API does not support this case well. – Michał Kłeczek Nov 01 '22 at 22:19
  • For that you can return ˋTransformer.noop()ˋ which acts like a failed precondition. See https://jqwik.net/docs/1.7.0/javadoc/net/jqwik/api/state/Transformer.html#noop() – johanneslink Nov 02 '22 at 06:26
  • Good to know. I am not sure if it is possible to do something along: Arbitraries.of(db.records()).map(...).orElse(noop()) – Michał Kłeczek Nov 02 '22 at 16:39

1 Answers1

1

As mentioned by johanneslink - I should implement Action.precondition() for this purpose. Thanks.