gherkin-linter 1.7.2

dotnet tool install --global gherkin-linter --version 1.7.2
                    
This package contains a .NET tool you can call from the shell/command line.
dotnet new tool-manifest
                    
if you are setting up this repo
dotnet tool install --local gherkin-linter --version 1.7.2
                    
This package contains a .NET tool you can call from the shell/command line.
#tool dotnet:?package=gherkin-linter&version=1.7.2
                    
nuke :add-package gherkin-linter --version 1.7.2
                    

Gherkin Linter for C# Projects

NuGet License

A pure C# implementation of a Gherkin linter for SpecFlow and other BDD frameworks, designed to integrate seamlessly with C# projects.

Table of Contents

Quick Start

  1. Install the GherkinLinter as a .NET tool:

    dotnet tool install --global gherkin-linter
    
  2. Lint your feature files:

    gherkin-linter lint
    
  3. Set up a Git pre-commit hook to automatically lint staged feature files:

    gherkin-linter install
    

Features

  • Lint Gherkin feature files to ensure quality and consistency
  • Built-in rules for common Gherkin issues
  • Custom rule support
  • Git pre-commit hook integration
  • Configurable via JSON
  • No Node.js or JavaScript dependencies
  • Strict mode for CI/CD pipelines
  • Quiet mode for reduced verbosity
  • Multi-targeting for .NET 6.0, 7.0, and 8.0

Installation

Install the Gherkin Linter as a global .NET tool from NuGet:

dotnet tool install --global gherkin-linter

To update to the latest version:

dotnet tool update --global gherkin-linter

To uninstall:

dotnet tool uninstall --global gherkin-linter

Usage

Command Line Interface

# Lint all feature files
gherkin-linter lint

# Lint only staged feature files
gherkin-linter lint --staged

# Lint a specific feature file
gherkin-linter lint --file path/to/feature.feature

# Use a specific configuration file
gherkin-linter lint --config path/to/config.json

# Use strict mode (returns non-zero exit code when violations are found)
gherkin-linter lint --strict

# Use quiet mode (display only essential information)
gherkin-linter lint --quiet

Git Pre-commit Hook Setup

# Install the pre-commit hook
gherkin-linter install

This will:

  1. Set up a Git pre-commit hook
  2. Create a default configuration file

Configuration

The linter uses a JSON configuration file named .gherkin-linter.json in your project root:

{
  "include": [
    "Features/**/*.feature",
    "**/*.feature"
  ],
  "exclude": [
    "bin/**/*.feature",
    "obj/**/*.feature"
  ],
  "rules": {
    "scenario-names": {
      "enabled": true
    },
    "no-empty-steps": {
      "enabled": true
    },
    "no-duplicate-scenario-names": {
      "enabled": true
    },
    "max-step-length": {
      "enabled": true,
      "config": {
        "length": 100
      }
    },
    "weak-language": {
      "enabled": true
    }
  },
  "custom_rules": []
}

Built-in Rules

Rule Description Configuration
scenario-names Ensures all scenarios have names None
no-empty-steps Ensures all steps have descriptions None
no-duplicate-scenario-names Checks for duplicated scenario names None
max-step-length Limits step length length: Maximum characters (default: 100)
weak-language Checks for weak language patterns in steps Customizable phrase mappings for Given/When and Then steps
indentation Enforces consistent indentation type, size, enforceConsistency, allowMixed, etc.

Rule Examples

scenario-names

This rule ensures that all scenarios have a name. Unnamed scenarios make it difficult to understand the purpose of the test.

# ❌ Bad - Unnamed scenario
Scenario:
  Given I am on the homepage
  When I click the login button
  Then I should see the login form

# ✅ Good - Named scenario
Scenario: User can navigate to login form
  Given I am on the homepage
  When I click the login button
  Then I should see the login form
no-empty-steps

This rule checks for steps that have no description.

# ❌ Bad - Empty step
Scenario: User login
  Given I am on the login page
  When 
  Then I should be logged in

# ✅ Good - All steps have descriptions
Scenario: User login
  Given I am on the login page
  When I enter my credentials and click login
  Then I should be logged in
no-duplicate-scenario-names

This rule ensures that all scenarios have unique names within a feature file.

# ❌ Bad - Duplicate scenario names
Scenario: User login
  Given I am on the login page
  When I enter valid credentials
  Then I should be logged in

Scenario: User login
  Given I am on the login page
  When I enter invalid credentials
  Then I should see an error message

# ✅ Good - Unique scenario names
Scenario: User login with valid credentials
  Given I am on the login page
  When I enter valid credentials
  Then I should be logged in

Scenario: User login with invalid credentials
  Given I am on the login page
  When I enter invalid credentials
  Then I should see an error message
max-step-length

This rule limits the length of step descriptions to improve readability.

# ❌ Bad - Step is too long
Scenario: User registration
  Given I am on the registration page
  When I enter my first name, last name, email address, phone number, street address, city, state, zip code, country, preferred contact method, and marketing preferences
  Then I should be registered

# ✅ Good - Steps are concise
Scenario: User registration
  Given I am on the registration page
  When I fill out the registration form with valid data
  And I submit the form
  Then I should be registered
weak-language

This rule identifies steps that use weak or ambiguous language.

# ❌ Bad - Uses weak language
Scenario: User login
  Given I am on the login page
  When I enter my credentials
  Then I should be able to see my dashboard

# ✅ Good - Uses specific language
Scenario: User login
  Given I am on the login page
  When I enter valid credentials and click login
  Then the dashboard is displayed with my account information
indentation

This rule enforces consistent indentation in Gherkin files.

# ❌ Bad - Inconsistent indentation
Feature: Test Feature
Scenario: Bad indentation
Given I am not indented
      When I have too much indentation
  Then I have wrong indentation

# ✅ Good - Consistent indentation
Feature: Test Feature
  
  Scenario: Good indentation
    Given I am properly indented
    When I have consistent spacing
    Then I follow the indentation rules
## Custom Rules

You can create custom rules by implementing the `IRuleProvider` interface in a new class library project:

```csharp
using System.Collections.Generic;
using GherkinLinter.Core;

namespace YourNamespace
{
    public class YourCustomRuleProvider : IRuleProvider
    {
        public IEnumerable<RuleViolation> ApplyRule(Feature feature, Dictionary<string, object> config)
        {
            var violations = new List<RuleViolation>();
            
            // Your rule logic here
            // Example: Check if feature name follows a pattern
            if (!feature.Name.StartsWith("JIRA-"))
            {
                violations.Add(new RuleViolation
                {
                    Message = "Feature name must start with JIRA-",
                    Line = feature.Line
                });
            }
            
            return violations;
        }
    }
}

Then reference your class library and add the rule to your configuration:

{
  "rules": {
    "your-custom-rule": {
      "enabled": true,
      "config": {
        "yourSetting": "value"
      }
    }
  },
  "custom_rules": [
    {
      "path": "path/to/your/assembly.dll",
      "config": {
        "additionalSetting": "value"
      }
    }
  ]
}

Integration with MSBuild

GherkinLinter includes MSBuild targets that can be used to integrate with your build process. The targets are automatically included when you install the NuGet package.


<PropertyGroup>
  
  <GherkinLinterEnabled>true</GherkinLinterEnabled>
  
  
  <GherkinLinterSkipInCI>true</GherkinLinterSkipInCI>
  
  
  <GherkinLinterPreserveTestAssemblies>true</GherkinLinterPreserveTestAssemblies>
</PropertyGroup>

For more details, see the MSBuild Integration section in the CI/CD Integration guide.

CI/CD Integration

GherkinLinter now includes features to better integrate with CI/CD environments and prevent interference with test discovery and execution:

  1. CI/CD Environment Detection - Automatically detects when running in common CI/CD systems
  2. Build Integration Toggle - Allows disabling linting during automated builds
  3. Test Assembly Preservation - Prevents linting in directories containing test assemblies
  4. MSBuild Integration - Conditional execution based on environment and configuration
# Skip linting in CI/CD environments
gherkin-linter lint --skip-in-ci

# Skip linting in directories containing test assemblies
gherkin-linter lint --preserve-test-assemblies

For detailed information, see the CI_CD_INTEGRATION.md guide.

Advanced Features

Strict Mode

The strict mode flag (--strict) makes the linter return a non-zero exit code when rule violations are found. This is particularly useful in CI/CD pipelines where you want the build to fail if there are linting errors.

# Normal mode - returns exit code 0 even with violations (for development)
gherkin-linter lint

# Strict mode - returns exit code 1 when violations are found (for CI/CD)
gherkin-linter lint --strict

Quiet Mode

The quiet mode flag (--quiet or -q) reduces the verbosity of the linter output, showing only essential information such as file paths with errors, the errors themselves, and a summary count. This is particularly useful in CI/CD pipelines or when you want to focus only on the errors without additional logging.

# Normal mode - shows detailed information about the linting process
gherkin-linter lint

# Quiet mode - shows only essential information (file paths, errors, and summary)
gherkin-linter lint --quiet

For more details about quiet mode, see QUIET_MODE.md.

Multi-targeting

The linter supports multiple .NET versions (6.0, 7.0, and 8.0), allowing you to use it with your preferred .NET runtime. The tool automatically selects the appropriate version based on what's installed on your system.

Troubleshooting

Common Issues

  • Configuration File Not Found: Ensure your .gherkin-linter.json file is in the root of your project.
  • Rules Not Working: Check that the rules are enabled in your configuration file.
  • Git Hook Not Working: Verify that the pre-commit hook is executable and properly installed.

Debugging

For more detailed output, use the verbose flag:

gherkin-linter lint --verbose

Contributing

Contributions are welcome! Here's how you can contribute:

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add some amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

Please ensure your code follows the existing style and includes appropriate tests.

License

MIT

Product Compatible and additional computed target framework versions.
.NET net6.0 is compatible.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 is compatible.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

This package has no dependencies.

Version Downloads Last Updated
1.7.2 160 6/18/2025
1.7.1 230 6/3/2025
1.7.0 167 6/2/2025
1.6.0 161 6/1/2025
1.5.0 216 5/20/2025
1.4.1 151 5/19/2025
1.4.0 147 5/19/2025
1.3.0 144 5/19/2025
1.2.1 146 5/19/2025
1.2.0 148 5/19/2025
1.1.1 154 5/18/2025
1.1.0 150 5/18/2025
1.0.6 148 5/18/2025

See RELEASE_NOTES_v1.7.2.md for detailed release notes