jqwik icon indicating copy to clipboard operation
jqwik copied to clipboard

Add debugging mode so arbitraries are easier to understand in the Java debugger

Open vlsi opened this issue 3 years ago • 6 comments

Testing Problem

Understanding the nature of Arbitrary, Combinator, etc in the runtime debugger is hard since the classes provide virtually no information that users can relate to the source code.

It is hard to debug exceptions coming from Arbitratries, and it is hard to understand the contents of Java debugger.

Suggested Solution

Add a mode where ArbitraryImpl, Combinator, etc would capture stacktrace (or just the most top frame excluding certain library-specific ones), so Arbitrary#toString could provide the source code location where the arbitrary was created.

An additional or alternative approach could be adding displayName or something like that to Arbitrary, Combiner, so users could provide meaningful names.

There's a similar case in Google Guice. When Guice identifies a configuration error, it attempts to provide the exact line in the user code which triggered the error. They do that by adding their own stacktrace filtering: https://google.github.io/guice/api-docs/latest/javadoc/com/google/inject/Binder.html#skipSources(java.lang.Class...)

Discussion

Collecting stack traces always might be time-consuming, so I suggest adding a feature flag. I'm not sure if there's a good way to require displayName from the end-user without redoing all the jqwik API.

JavaScript treats .displayName for naming "anonymous functions" for quite some time now: https://bugs.chromium.org/p/chromium/issues/detail?id=17356, https://rreverser.com/gh-stack-displayname/

vlsi avatar May 16 '22 13:05 vlsi

A relavant issue: net.jqwik.engine.properties.arbitraries.randomized.IgnoreExceptionGenerator@4e4395c missed more than 10000 times.

vlsi avatar May 16 '22 19:05 vlsi

My current workaround for "missed more than 10000 times" is to add maxMisses parameter with a random (hard-coded) value, so when I see Filtering [net.jqwik.api.RandomGenerator$$Lambda$497/0x000000080042a440@6391b276] missed more than 934 times I can check for 934 in my code.

vlsi avatar May 18 '22 07:05 vlsi

Add a mode where ArbitraryImpl, Combinator, etc would capture stacktrace (or just the most top frame excluding certain library-specific ones), so Arbitrary#toString could provide the source code location where the arbitrary was created.

That means it would have to be captured on each creation of an arbitrary, right? And then the (potentially filtered) stack trace used in toString()? Quite some overhead so using a property attribute with a default would definitely be required.

jlink avatar Jun 03 '22 08:06 jlink

That means it would have to be captured on each creation of an arbitrary, right? And then the (potentially filtered) stack trace used in toString()?

Exactly.

Quite some overhead

That is why I think it should be disabled by default, and it should be activated on demand only, or only when jqwik detects a failure.

For instance, if jqwik is about to print the final results, it might re-execute the test with debugging mode, so the output stacktrace is easier to understand.

vlsi avatar Jun 03 '22 09:06 vlsi

An additional or alternative approach could be adding displayName or something like that to Arbitrary, Combiner, so users could provide meaningful names.

Something like that has been in my backlog for a while. There're two reasons that I've refrained from doing it:

  • It would require an implementation for each and every arbitrary to be useful
  • Some interesting stuff just cannot be captured at runtime, like the concrete type of a type variable or the actual predicate of a filtering lambda. So the description string would only be so useful.

jlink avatar Jun 03 '22 09:06 jlink

For instance, if jqwik is about to print the final results, it might re-execute the test with debugging mode, so the output stacktrace is easier to understand.

It wouldn't even have to re-execute the full property, just the arbitrary creation phase should suffice.

jlink avatar Jun 03 '22 09:06 jlink