Troubleshooting
Common problems, what causes them, and how to fix them. Each entry starts with what you actually see.
Inspect generation in the build log
You see: generation fails or produces an unexpected result, but the normal build output does not show enough detail to explain why.
SpecBinder generates test code while the Java compiler runs its annotation processor, so its
diagnostics appear during compilation. Run mvn test-compile (or mvn test) or
./gradlew compileTestJava, then inspect the generation messages in the build log.
Increase the detail for a marker class with the verbosity option:
@Gherkin2JUnit("specs/ShoppingCart.specb")
@Gherkin2JUnitOptions(verbosity = Verbosity.VERBOSE)
public abstract class ShoppingCartFeature { }
The levels are cumulative, so each one includes the output from the less detailed levels:
| Level | What it emits |
|---|---|
SILENT | Error diagnostics only, with no banner or summary. |
NORMAL (default) | Errors, warnings, the startup banner, and the end-of-round summary. |
VERBOSE | Adds per-class processing headers, resolved spec paths, per-feature progress, and reasons for skipped work. |
DEBUG | Adds full stack traces, parsed Gherkin AST summaries, JavaPoet model summaries, and per-step decisions. |
Start with VERBOSE when tracing which specs SpecBinder found and what it generated. Use DEBUG
when you need the processor's internal parsing and code-generation detail. The annotation-level
setting overrides the global -Aspecbinder.verbosity=… processor argument; see
verbosity for the configuration reference.
The generated class doesn't exist
You see: Cannot resolve symbol 'ShoppingCartScenarios', or your hand-written test class
can't find the class it extends.
SpecBinder writes that class during compilation, so it only appears once the project has been built with annotation processing switched on.
-
Build the project. Nothing is generated until compilation runs. In IntelliJ, Build → Build Project; on the command line,
mvn test-compileor./gradlew compileTestJava.The SpecBinder IntelliJ plugin can take this step off your hands. Under Settings → Tools → SpecBinder → General → When a spec file is saved, choose Recompile marker class and saving a spec file rebuilds its generated tests there and then, so editing a step and re-running is all you do.
-
Check annotation processing is enabled in your IDE. In IntelliJ: Settings → Build, Execution, Deployment → Compiler → Annotation Processors → Enable annotation processing.
-
Check the generated sources folder is treated as source. Generated classes land in
target/generated-test-sources/test-annotations/(Maven) orbuild/generated/sources/annotationProcessor/(Gradle). Maven and Gradle add these automatically; if your IDE hasn't caught up, re-import the project. -
Check the name you're expecting. The class is named after the spec file, not after the class you annotated —
Checkout.specbproducesCheckoutScenarios. See the naming rules.
The generated class is out of date
You see: you changed a step's wording, but the generated class still has the old method, or your build still fails on a step you just renamed.
The generated class is rebuilt when the project is compiled. Editing a spec file on its own does
not trigger that in every setup — some build tools consider the compile task up to date because
no .java file changed.
- Rebuild rather than relying on an incremental build:
mvn clean test-compile, or./gradlew compileTestJava --rerun-tasks. - In IntelliJ, set Settings → Tools → SpecBinder → General → When a spec file is saved to Recompile marker class, and saving the spec regenerates its tests immediately — see Settings → General.
A scenario with no steps fails
You see: a scenario you have sketched out but not written steps for yet fails when the tests run.
That is the default: emptyScenarioBehavior is FAIL, so an unfinished scenario shows up rather
than passing quietly.
If you would rather they were reported as aborted while you work, set the behaviour on the class you annotate:
@Gherkin2JUnit("specs/ShoppingCart.specb")
@Gherkin2JUnitOptions(emptyScenarioBehavior = EMPTY_ELEMENT_BEHAVIOUR.ABORT)
public abstract class ShoppingCartFeature { }
emptyRuleBehavior does the same for a Rule with no scenarios. COMPILATION_ERROR is the third
option, if an unfinished scenario should stop the build outright.
A step parameter has the wrong type
You see: a step method you implemented no longer matches, because a parameter that was an
Integer is now a String.
Parameter types are inferred from the values in the spec, and the inference covers every
occurrence of that step in the file. If one scenario passes "12" and another passes "twelve",
the parameter widens to String everywhere — including in the method you already wrote.
Either keep the values consistent, or accept the wider type and convert inside the step.
My existing step method isn't being picked up
You see: SpecBinder asks you to implement a step you have already written.
Steps are matched by method name. SpecBinder derives the name from the step's wording, so the method has to match that name exactly, and it has to be visible from the generated class — somewhere in the hierarchy of the class you annotated.
The reliable way to get the name right is to let SpecBinder generate the step first, then move that method to wherever you want it implemented.
If you are coming from Cucumber and expect your @Given/@When annotations to be matched
instead, that is off by default — see
Migrating from Cucumber.
Still stuck?
Ask on the Q&A page — questions and answers there are public, so the next person with the same problem finds it too.