Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.

A second Cucumber or Behave feature file normally uses the step definitions already available to the test run; it does not need its own implementation file. If its steps show as undefined, first check that the definitions were discovered, then compare the complete step text and arguments. The feature filename itself does not determine which definition is used.

How step definitions are found and matched

A feature file describes scenarios in Gherkin. Before scenarios run, the test framework loads step definitions into a registry. Each step’s text is matched against the expressions or decorators registered for that run. In Cucumber, definitions are not inherently tied to one feature file, and the Given, When, and Then keywords do not create separate matching namespaces: the text after the keyword must match a definition. See the Cucumber API.

That means the key comparison is not “first feature versus second feature”; it is “what text does the second feature use, and which definitions did this run load?” Cucumber permits one or multiple step-definition files, while its step organization guidance recommends useful grouping and avoiding duplication. Behave similarly imports Python files from the feature’s steps directory before execution; its feature setup documentation describes that layout.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Identify the actual failure before changing code

“The step failed” can describe several different problems. Check the runner output and classify the state before editing definitions; each state points to a different fix.

Result What it means First thing to check
Undefined No loaded definition matches the step text, or the file containing its definition was not discovered. Glue/steps discovery and the complete text after the keyword.
Ambiguous or duplicate More than one loaded definition matches the same step, so the framework cannot select one reliably. Overlapping expressions or duplicate definitions in different files.
Arity mismatch The definition’s expected arguments do not match the values supplied by the expression or step. Capture groups, expression parameters, and data-table or doc-string arguments.
Failed A matching implementation ran, but its code raised an error or an assertion did not pass. The implementation’s error, test data, and application state—not discovery.

Cucumber distinguishes undefined steps, ambiguous matches, and argument-arity problems in its FAQ and API documentation. If the second feature reports a failure rather than undefined, the definition has been found; debug what it does rather than adding another definition.

Check the discovery path for your framework

Cucumber-JVM: verify the runner’s glue

For Cucumber-JVM, the default search is the package containing the runner class and its subpackages. If definitions are elsewhere, set an explicit glue package that includes them. The Cucumber FAQ identifies an incorrect glue path as a common reason a step remains undefined even though an implementation exists.

For example, if the paths are:

  • Feature: src/test/resources/features/account/login.feature
  • Runner: src/test/java/com/example/run/RunCucumberTest.java
  • Definitions: src/test/java/com/example/steps/AccountSteps.java

the runner package alone, com.example.run, does not include the sibling package com.example.steps. Set the runner’s glue to the package containing the definitions, such as com.example.steps, or move the definitions into the runner package or a subpackage. In a JUnit runner using @CucumberOptions, the setting is written as glue = "com.example.steps". Keep the feature path and glue path conceptually separate: the feature path selects Gherkin files, while glue selects Java packages containing definitions.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Behave: confirm the feature tree and steps directory

Behave expects step modules in a steps directory associated with the feature tree. A typical layout is:

  • features/account/login.feature
  • features/steps/account_steps.py

Check that the second feature is under the intended features tree, that the implementation module is under its steps directory, and that the module contains the expected Behave decorators. A file elsewhere in the project is not necessarily imported for that feature run. The Behave API documentation describes step decorators and matching.

Compare the complete step wording

Once discovery is right, compare the second feature’s entire step text with the registered expression. Match spelling, punctuation, parameter positions, and the literal wording around parameters. Similar meaning is not enough: “the user logs in” and “the user signs in” are different text unless the expression covers both.

For example, suppose an existing definition is expressed as:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
@When("the user logs in as {string}")
public void userLogsInAs(String username) {
    // perform login
}

This step matches When the user logs in as "alex", but not When the user signs in as "alex". Either make the new feature use the shared wording:

When the user logs in as "alex"

or deliberately broaden or add a suitable expression. Do not add a near-duplicate without checking the rest of the loaded definitions; it can turn an undefined result into an ambiguous one. Cucumber expressions can capture values and pass them to the method, as described in the API.

In Behave, apply the same comparison to the string in the decorator and the step text in the feature. A changed verb, omitted phrase, or different parameter shape may prevent a match. Use a shared, clear phrase when the scenarios describe the same behavior; create a different step only when the behavior itself is meaningfully different.

Check parameters, tables, and doc strings

A definition may match the visible wording but still have an argument-shape problem. Inspect the capture groups or expression parameters and verify that the implementation method accepts the corresponding values. Also check whether the scenario step includes a data table or doc string: these are additional step arguments and must be handled in the implementation. Cucumber documents arity mismatch as distinct from “no definition found” in its FAQ.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  • If you add a parameter in the feature, make sure the expression captures it and the method signature accepts it.
  • If you alter a regular expression, verify that its capture groups still line up with the method arguments.
  • If only the second feature attaches a table or doc string, update the implementation to accept that argument or change the scenario structure if it is not intended.

Do not treat an argument mismatch as a reason to create another definition for the same step. First decide whether the scenario data or the implementation signature is wrong, then align them.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Remove duplicate or overly broad definitions

All definitions loaded for a run are available when matching occurs. If two files contain definitions that both match a step, Cucumber can report an ambiguous or duplicate definition rather than choosing based on which feature contains the step. Search all loaded step files for the phrase and for broad patterns or expressions that may overlap it. Remove the redundant definition or narrow the expressions so each step has one intended match.

This also explains why adding a second feature-specific file can make the problem worse: the new file may duplicate a reusable definition that was already loaded. Cucumber’s anti-pattern guidance cautions against feature-coupled step definitions because they reduce reuse and increase duplication and maintenance. Group definitions by business capability, such as account access or checkout, rather than creating one implementation file per feature.

Run a focused check, then the full suite

  1. Run only the second feature using the same runner and the same glue or steps configuration used for the first.
  2. Read the exact status. If it is now passed or failed, the undefined-definition problem is resolved; a failure requires debugging the implementation or scenario instead.
  3. If it is ambiguous or reports an argument problem, fix the overlapping match or argument shape rather than changing discovery.
  4. Run the full suite after the focused check. Other scenarios can reveal duplicate matches or regressions caused by changing a shared definition.

This sequence uses the same load-and-match lifecycle described by Cucumber and Behave: first ensure the relevant definitions load, then validate one scenario, then check the effect of shared changes across the suite.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Common causes and fixes

  • Only the second feature is undefined: confirm it is included in the feature selection and that the runner uses the expected glue package or Behave feature tree.
  • Definition exists but is not found: verify the definition’s package or steps directory is actually part of the current run; a source file outside the discovered location is not automatically available.
  • Nearly identical phrase: compare the full text, including parameter wording and punctuation; align it with the intended reusable expression.
  • Definition matches but argument error appears: align the expression’s captures and method signature, including any table or doc-string argument.
  • Ambiguous step after adding a file: search all loaded files for overlapping patterns and retain one unambiguous implementation.
  • Implementation runs and then fails: stop changing glue or matching expressions and inspect the exception, assertion, and scenario-specific data.

Or skip the browser setup

This is a separate option for website screenshot capture, not a fix for Cucumber or Behave step definitions. If you also need screenshots from tests or other developer workflows, ScreenshotNeo provides a one-request screenshot API. For example, this cURL call saves a WebP shot of the target page:

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

See the ScreenshotNeo API documentation for request options. Its capture flow accepts cookie/consent banners like a visitor and removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture; each of those steps can be turned off. Bot checks, blank pages, timeouts, failed loads, and cache hits are not billed, and responses identify the page verdict and billing status in headers. An MCP server provides take_screenshot, get_page_info, and capture_pdf for AI agents. The free plan includes 1,000 shots per month with no card; paid plans start at $5 for 3,000 shots.

Sign up for ScreenshotNeo’s free 1,000 screenshots a month, with no card required.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.