Skip to main content

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:

LevelWhat it emits
SILENTError diagnostics only, with no banner or summary.
NORMAL (default)Errors, warnings, the startup banner, and the end-of-round summary.
VERBOSEAdds per-class processing headers, resolved spec paths, per-feature progress, and reasons for skipped work.
DEBUGAdds 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.

  1. Build the project. Nothing is generated until compilation runs. In IntelliJ, Build → Build Project; on the command line, mvn test-compile or ./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.

  2. Check annotation processing is enabled in your IDE. In IntelliJ: Settings → Build, Execution, Deployment → Compiler → Annotation Processors → Enable annotation processing.

  3. Check the generated sources folder is treated as source. Generated classes land in target/generated-test-sources/test-annotations/ (Maven) or build/generated/sources/annotationProcessor/ (Gradle). Maven and Gradle add these automatically; if your IDE hasn't caught up, re-import the project.

  4. Check the name you're expecting. The class is named after the spec file, not after the class you annotated — Checkout.specb produces CheckoutScenarios. 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.