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.

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.