Skip to main content

Feature Linting

KTestify ships a built-in linter for .feature files. It catches problems that Cucumber would only surface mid-run, or not at all: tabs instead of spaces, undeclared topic aliases, and asset files that do not exist on disk.

Linting runs before any Cucumber or plugin startup, so it is fast enough for a pre-commit hook or a dedicated CI job.


Running the linter​

Docker image​

docker run --rm \
-v "$PWD/features:/workspace/features" \
-v "$PWD/assets:/workspace/assets" \
ghcr.io/ktestify/ktestify-cucumber:latest \
lint /workspace/features \
--assets-dir /workspace/assets

Fat JAR​

java -jar ktestify-cucumber.jar lint features/

Exit codes​

CodeMeaning
0No ERROR-severity violations
1At least one ERROR-severity violation (or warnings over --max-warnings)
2Usage error, or no .feature files found

Options​

OptionDescription
--format <fmt>text (default), json, or codeclimate (GitLab Code Quality)
--no-semanticSkip the domain rules (alias, file, and step definition checks)
--no-file-checkSkip on-disk asset file-existence checks (D003/D004)
--assets-subdir <name>Assets folder beside each feature file (default: assets)
--assets-dir <path>Absolute assets folder, overrides --assets-subdir
--disable <ids>Comma-separated rule ids to disable, e.g. G013,G001
--ignore-tags <tags>Comma-separated tags to skip, e.g. @WIP,@Skip (@ optional, alias --ignore-tagged). A tagged feature is skipped entirely; a tagged scenario (or rule) is excluded from the report
--max-warnings <n>Fail (exit 1) if warnings exceed this count; -1 = never

GitLab Code Quality​

The codeclimate format emits the GitLab Code Quality JSON array. Pipe it to a file and expose it as a report artifact:

lint-features:
script:
- docker run --rm -v "$PWD:/workspace" ghcr.io/ktestify/ktestify-cucumber:latest
lint /workspace/features --format codeclimate > gl-code-quality-report.json
artifacts:
reports:
codequality: gl-code-quality-report.json

Rules​

Structural rules (G*) check the Gherkin file itself. Domain rules (D*) check ktestify-specific semantics. Files that Cucumber cannot parse at all are reported through G007.

Structural rules​

RuleSeverityDescription
G001errorTab character found; use spaces for indentation
G002warnTrailing whitespace
G003warnFile does not end with a single newline
G004errorExactly one Feature declaration is required per file
G005errorFeature has no name
G006errorScenario has no name
G007warnLine does not start with a recognised Gherkin keyword (includes parse errors)
G008errorStep keyword has no text
G009warnFeature has no scenarios
G010errorMalformed table row: every row must start and end with |
G011errorTable row column count does not match the header
G012warnUnexpected indentation (two-space house style)
G013warnMore than one consecutive blank line
G014errorTable row is not attached to any step
G015errorContent appears before the Feature declaration
G016errorStep outside of a Background or Scenario
G017warnEmpty header cell in data table

Domain rules​

RuleSeverityDescription
D001errorFile value (a cell ending in a known extension) contains whitespace
D002errortopicAlias / schemaAlias / namespaceAlias used in a Scenario is not declared in any Background table
D003errorReferenced file / files value is missing from the assets folder
D004warnAssets directory not found; file-existence checks skipped
D005errorUndefined step: no matching step definition in ktestify-cucumber or its plugins

Alias declaration is derived from the real step catalogue: the Background steps namespace(s), input topic, output topic, and schema(s) declare the aliases that Scenarios may reference.


Example output​

features/orders.feature
12:1 error D002 'out' used as topicAlias is not declared in any Background input/output topic table.
18:1 error D003 Referenced file 'expected.json' (column 'file') is missing from assets folder 'features/assets'.

2 error(s), 0 warning(s)