Introduction to Gauge Framework

Gauge is a modern, open-source test automation framework from ThoughtWorks that brings a fresh perspective to behavior-driven development (BDD). Unlike traditional BDD (as discussed in BDD: From Requirements to Automation) tools that use domain-specific languages like Gherkin, Gauge uses Markdown for writing specifications, making it more accessible and familiar to technical and non-technical team members alike.

This comprehensive guide explores Gauge’s unique approach to BDD (as discussed in Cucumber BDD Automation: Complete Guide to Behavior-Driven Development Testing), covering Markdown-based specifications, language-independent architecture, parallel execution capabilities, plugin ecosystem, and detailed comparison with Cucumber.

When implementing Gauge for BDD testing, solid test case design techniques help you write effective specifications. Integrating Gauge with continuous testing in DevOps pipelines ensures rapid feedback, while a comprehensive test automation strategy maximizes the value of your BDD test suite.

Markdown Specifications: A Natural Approach

Gauge specifications use Markdown format, eliminating the need to learn new syntax while providing rich formatting capabilities.

Basic Gauge Specification

# User Authentication

## Successful login with valid credentials
* Navigate to login page
* Enter username "john.doe@example.com"
* Enter password "SecurePass123"
* Click login button
* Verify user is redirected to dashboard
* Verify welcome message "Welcome, John"

## Failed login with invalid credentials
* Navigate to login page
* Enter username "john.doe@example.com"
* Enter password "wrongpassword"
* Click login button
* Verify error message "Invalid credentials"
* Verify user remains on login page

Specification Structure

ElementMarkdown SyntaxPurpose
Specification# TitleTop-level container
Scenario## DescriptionIndividual test case
Step* ActionTest step
Tagtags: smoke, criticalCategorization
Comment// CommentDocumentation
ConceptReusable step groupStep abstraction

Advanced Specification Features

# E-Commerce Shopping Cart
tags: shopping, critical

## Context Setup
* Login as "standard_user"
* Navigate to products page

## Add product to cart
* Add product "Laptop Computer" to cart
* Verify cart count is "1"
* Verify cart total is "$999.99"

## Add multiple quantities
* Add "3" units of product "USB Cable" to cart
* Verify cart count is "3"
* Verify cart total is "$29.97"

## Remove product from cart
* Add product "Wireless Mouse" to cart
* Remove product "Wireless Mouse" from cart
* Verify cart is empty
* Verify cart count is "0"

Data-Driven Testing with Tables

# Login Validation
tags: validation, parametrized

## Validate login with different credentials
|username|password|expected_result|
|--------|--------|---------------|
|valid@example.com|ValidPass123|Welcome to Dashboard|
|invalid@example.com|anything|User not found|
|valid@example.com|wrongpass|Invalid credentials|
|@invalid.com|ValidPass123|Invalid email format|
|valid@example.com|123|Password too short|

* Verify login with credentials <username>, <password> shows <expected_result>

Language Independence: True Polyglot Testing

Gauge’s architecture allows implementing step definitions in any programming language, providing unprecedented flexibility.

Java Implementation

// src/test/java/StepImplementation.java
package com.example;

import com.thoughtworks.gauge.Step;
import com.thoughtworks.gauge.Table;
import com.thoughtworks.gauge.TableRow;
import pages.LoginPage;
import pages.DashboardPage;

public class StepImplementation {
    private LoginPage loginPage;
    private DashboardPage dashboardPage;

    @Step("Navigate to login page")
    public void navigateToLogin() {
        loginPage = new LoginPage();
        loginPage.open();
    }

    @Step("Enter username <username>")
    public void enterUsername(String username) {
        loginPage.enterUsername(username);
    }

    @Step("Enter password <password>")
    public void enterPassword(String password) {
        loginPage.enterPassword(password);
    }

    @Step("Click login button")
    public void clickLogin() {
        dashboardPage = loginPage.clickLogin();
    }

    @Step("Verify user is redirected to dashboard")
    public void verifyDashboard() {
        assertTrue(dashboardPage.isDisplayed());
    }

    @Step("Verify login with credentials <username>, <password> shows <result>")
    public void verifyLoginWithCredentials(String username, String password, String result) {
        navigateToLogin();
        enterUsername(username);
        enterPassword(password);
        clickLogin();
        assertEquals(result, loginPage.getMessageOrDashboardText());
    }
}

JavaScript/TypeScript Implementation

// tests/step_implementations/authentication.ts
import { Step, Table } from "gauge-ts";
import { LoginPage } from "../pages/LoginPage";
import { DashboardPage } from "../pages/DashboardPage";
import { expect } from "@playwright/test";

let loginPage: LoginPage;
let dashboardPage: DashboardPage;

Step("Navigate to login page", async function() {
    loginPage = new LoginPage(gauge.page);
    await loginPage.navigate();
});

Step("Enter username <username>", async function(username: string) {
    await loginPage.enterUsername(username);
});

Step("Enter password <password>", async function(password: string) {
    await loginPage.enterPassword(password);
});

Step("Click login button", async function() {
    await loginPage.clickLogin();
    dashboardPage = new DashboardPage(gauge.page);
});

Step("Verify user is redirected to dashboard", async function() {
    await expect(dashboardPage.container).toBeVisible();
});

Step("Verify welcome message <message>", async function(message: string) {
    const actual = await dashboardPage.getWelcomeMessage();
    expect(actual).toBe(message);
});

Step("Verify login with credentials <username>, <password> shows <result>",
    async function(username: string, password: string, expectedResult: string) {
        await loginPage.navigate();
        await loginPage.enterUsername(username);
        await loginPage.enterPassword(password);
        await loginPage.clickLogin();

        const actualResult = await loginPage.getMessageOrDashboardText();
        expect(actualResult).toContain(expectedResult);
});

Python Implementation

# step_impl/authentication_steps.py
from getgauge.python import step, Table
from pages.login_page import LoginPage
from pages.dashboard_page import DashboardPage

login_page = None
dashboard_page = None

@step("Navigate to login page")
def navigate_to_login():
    global login_page
    login_page = LoginPage()
    login_page.navigate()

@step("Enter username <username>")
def enter_username(username):
    login_page.enter_username(username)

@step("Enter password <password>")
def enter_password(password):
    login_page.enter_password(password)

@step("Click login button")
def click_login():
    global dashboard_page
    login_page.click_login()
    dashboard_page = DashboardPage()

@step("Verify user is redirected to dashboard")
def verify_dashboard_redirect():
    assert dashboard_page.is_displayed(), "Dashboard not displayed"

@step("Verify welcome message <message>")
def verify_welcome_message(message):
    actual = dashboard_page.get_welcome_message()
    assert actual == message, f"Expected '{message}', got '{actual}'"

@step("Verify login with credentials <username>, <password> shows <result>")
def verify_login_credentials(username, password, expected_result):
    navigate_to_login()
    enter_username(username)
    enter_password(password)
    click_login()

    actual_result = login_page.get_message_or_dashboard_text()
    assert expected_result in actual_result

Parallel Execution: Built-in Performance

Gauge provides native parallel execution capabilities without external plugins.

Parallel Execution Configuration

# env/default/default.properties

# Number of parallel streams
gauge_parallel_streams = 4

# Execution strategy: lazy (default) or eager
gauge_execution_type = lazy

# Enable/disable screenshots on failure
screenshot_on_failure = true

# Report configuration
gauge_reports_dir = reports
overwrite_reports = true

# Browser configuration for parallel execution
BROWSER = chrome
HEADLESS = true

Running Tests in Parallel

# Run with 4 parallel streams
gauge run specs --parallel --max-workers=4

# Run specific tags in parallel
gauge run specs --tags "smoke & critical" --parallel

# Parallel execution with custom streams
gauge run specs --parallel --max-workers=8 --strategy=eager

# Parallel with custom environment
gauge run specs --env qa --parallel --max-workers=4

Parallel Execution Performance Comparison

Test Suite SizeSequential2 Workers4 Workers8 Workers
100 scenarios450s235s (48% faster)125s (72% faster)70s (84% faster)
500 scenarios2100s1100s (48% faster)580s (72% faster)320s (85% faster)
1000 scenarios4200s2200s (48% faster)1150s (73% faster)630s (85% faster)

Concepts: Reusable Step Groups

Concepts allow grouping related steps into reusable components, promoting DRY principles.

Defining Concepts

<!-- concepts/login_concepts.cpt -->

# Login as user <username> with password <password>
* Navigate to login page
* Enter username <username>
* Enter password <password>
* Click login button

# Login as admin
* Login as user "admin@example.com" with password "admin123"
* Verify admin dashboard is displayed

# Login as standard user
* Login as user "user@example.com" with password "user123"
* Verify user dashboard is displayed

# Add product <product_name> to cart
* Search for product <product_name>
* Click on product <product_name>
* Click add to cart button
* Verify product added confirmation

# Complete checkout with <payment_method>
* Navigate to cart
* Click checkout button
* Fill shipping information
* Select payment method <payment_method>
* Confirm order
* Verify order confirmation

Using Concepts in Specifications

# E-Commerce Complete Flow
tags: integration, e2e

## Successful purchase flow
* Login as standard user
* Add product "Laptop Pro" to cart
* Add product "Wireless Mouse" to cart
* Complete checkout with "Credit Card"
* Verify order total is "$1,029.98"
* Verify order confirmation email sent

## Guest checkout
* Add product "USB Cable" to cart
* Complete checkout with "PayPal"
* Verify order confirmation page

Hooks and Execution Lifecycle

Gauge provides comprehensive hooks for test lifecycle management.

Java Hooks Implementation

// src/test/java/Hooks.java
package com.example;

import com.thoughtworks.gauge.*;
import org.openqa.selenium.WebDriver;
import utils.DriverFactory;
import utils.DatabaseUtils;

public class Hooks {
    private WebDriver driver;

    @BeforeSuite
    public void beforeSuite(ExecutionContext context) {
        System.out.println("Starting test suite: " +
                          context.getCurrentSpecification().getName());
        DatabaseUtils.initializeTestDatabase();
    }

    @BeforeSpec
    public void beforeSpec(ExecutionContext context) {
        System.out.println("Starting spec: " +
                          context.getCurrentSpecification().getName());
    }

    @BeforeScenario
    public void beforeScenario(ExecutionContext context) {
        System.out.println("Starting scenario: " +
                          context.getCurrentScenario().getName());
        driver = DriverFactory.getDriver();
        Gauge.writeMessage("Browser launched");
    }

    @BeforeStep
    public void beforeStep(ExecutionContext context) {
        // Can be used for logging or screenshots
    }

    @AfterStep
    public void afterStep(ExecutionContext context) {
        if (context.getCurrentStep().getIsFailing()) {
            byte[] screenshot = DriverFactory.takeScreenshot(driver);
            Gauge.writeMessage("Step failed, screenshot attached");
        }
    }

    @AfterScenario
    public void afterScenario(ExecutionContext context) {
        if (context.getCurrentScenario().getIsFailing()) {
            byte[] screenshot = DriverFactory.takeScreenshot(driver);
            Gauge.captureScreenshot();
        }
        driver.quit();
    }

    @AfterSpec
    public void afterSpec(ExecutionContext context) {
        System.out.println("Completed spec: " +
                          context.getCurrentSpecification().getName());
    }

    @AfterSuite
    public void afterSuite(ExecutionContext context) {
        System.out.println("Test suite completed");
        DatabaseUtils.cleanupTestDatabase();
    }
}

Gauge vs Cucumber: Comprehensive Comparison

Feature Comparison Table

FeatureGaugeCucumber
Specification FormatMarkdownGherkin (custom DSL)
Learning CurveLow (familiar Markdown)Medium (new syntax)
Language SupportJava, JavaScript, Python, Ruby, C#, GoJava, JavaScript, Ruby, many more
Parallel ExecutionBuilt-in native supportRequires plugins (cucumber-jvm-parallel)
IDE SupportVS Code, IntelliJ IDEA pluginsExcellent (IntelliJ, Eclipse, VS Code)
Concepts/ReusabilityBuilt-in concept filesStep definition reuse only
Data TablesNative Markdown tablesGherkin tables
ReportingHTML, XML, JSON reportsMultiple plugin options
Community SizeGrowing (ThoughtWorks backed)Large, established
DocumentationExcellentExcellent

Syntax Comparison

Gauge Specification:

# User Login
tags: authentication

## Successful login
* Navigate to login page
* Login as user "john@example.com" with password "pass123"
* Verify dashboard is displayed

Cucumber Feature:

@authentication
Feature: User Login

  Scenario: Successful login
    Given I navigate to login page
    When I login as user "john@example.com" with password "pass123"
    Then I should see the dashboard

When to Choose Gauge

Choose Gauge when:

  • Team prefers Markdown over custom DSL
  • Need built-in parallel execution without plugins
  • Want language-independent architecture from start
  • Concepts and reusable step groups are priority
  • Working with teams familiar with Markdown
  • Need lightweight, modern BDD tool

Choose Cucumber when:

  • Large existing Cucumber infrastructure
  • Need extensive plugin ecosystem
  • Team already familiar with Gherkin
  • Require broad language support
  • Want established community and resources

Gauge Plugin Ecosystem

# Install essential plugins
gauge install java
gauge install javascript
gauge install python
gauge install html-report
gauge install xml-report
gauge install json-report
gauge install screenshot
gauge install spectacle  # Beautiful HTML reports

# Install IDE plugins
# VS Code: Search "Gauge" in extensions
# IntelliJ IDEA: File -> Settings -> Plugins -> Gauge

# List installed plugins
gauge list

# Update plugins
gauge update --all

Practical Use Case: E-Commerce Testing

# Complete E-Commerce Purchase Flow
tags: critical, integration, e2e

## Context: Product catalog setup
* Initialize database with test products
* Ensure inventory stock levels are sufficient

## Guest user completes purchase
* Navigate to home page
* Search for product "Laptop Pro 15"
* Add product to cart with quantity "1"
* Proceed to checkout as guest
* Fill guest checkout information
  |field|value|
  |-----|-----|
  |email|guest@example.com|
  |firstName|John|
  |lastName|Doe|
  |address|123 Main St|
  |city|San Francisco|
  |state|CA|
  |zip|94105|
  |country|USA|
* Select shipping method "Standard"
* Enter payment details
  |cardNumber|expiry|cvv|name|
  |----------|------|---|-----|
  |4532123456789010|12/25|123|John Doe|
* Submit order
* Verify order confirmation number is generated
* Verify order confirmation email sent to "guest@example.com"
* Verify inventory decreased for "Laptop Pro 15"

## Registered user with saved details
* Login as standard user
* Search for product "Wireless Mouse"
* Add product to cart with quantity "2"
* Proceed to checkout
* Select saved shipping address "Home"
* Select saved payment method "Visa ending 9010"
* Apply coupon code "SAVE10"
* Verify discount applied is "10%"
* Submit order
* Verify order total is "$53.99"
* Verify loyalty points earned "54"

Best Practices for Gauge

1. Specification Organization

specs/
├── api/
│   ├── user_management.spec
│   └── product_catalog.spec
├── ui/
│   ├── authentication.spec
│   ├── shopping_cart.spec
│   └── checkout.spec
├── integration/
│   └── complete_purchase_flow.spec
└── concepts/
    ├── login_concepts.cpt
    ├── cart_concepts.cpt
    └── checkout_concepts.cpt

2. Effective Step Writing

<!-- Good: Declarative, business-focused -->
* Login as admin
* Add product to cart
* Complete checkout

<!-- Bad: Imperative, UI-focused -->
* Click on login link
* Type "admin" in username field
* Type "pass" in password field
* Click submit button

3. Concept Usage

<!-- Reusable concept -->
# Purchase product <name> as <user_type>
* Login as <user_type>
* Search and add <name> to cart
* Complete checkout with default payment
* Verify order confirmation

<!-- Usage in spec -->
* Purchase product "Laptop" as "premium_user"
* Purchase product "Mouse" as "standard_user"

Conclusion

Gauge represents a modern evolution in BDD testing, offering a refreshing alternative to traditional frameworks. Its use of Markdown specifications eliminates the learning curve of custom DSLs, while its language-independent architecture and built-in parallel execution provide flexibility and performance.

Key advantages of Gauge:

  • Accessibility: Markdown format is familiar and easy to learn
  • Flexibility: True language independence allows mixing technologies
  • Performance: Native parallel execution without plugins
  • Reusability: Concepts provide powerful abstraction mechanism
  • Modern: Built with current best practices and tooling

Whether you’re starting a new project or looking for a Cucumber (as discussed in Serenity BDD Integration: Living Documentation and Advanced Test Reporting) alternative, Gauge deserves serious consideration. Its thoughtful design, active development by ThoughtWorks, and growing community make it a compelling choice for modern test automation.

For teams valuing simplicity, performance, and language flexibility, Gauge offers a powerful BDD solution that bridges business requirements and automated testing without unnecessary complexity.

See Also