Gremlins Mutation Testing for Go

repository·main·Indexed 18 days ago

https://github.com/go-gremlins/gremlins

Gremlins is a mutation testing tool for Go, optimized for small-to-medium modules like microservices. It improves test quality by injecting mutations into code to verify if existing tests can detect them. Key features include coverage-driven testing, incremental testing for PR changes, and quality gate thresholds for efficacy and mutant coverage. It is provided as a CLI tool with the primary `unleash` command for executing mutation tests.

Tokens
10.6K
Snippets
49
Records
74
Agent score
61%

What's inside Gremlins

  1. Overview of Gremlins mutation testing

    main

    Gremlins is a mutation testing tool designed for Go, specifically optimized for small-to-medium sized modules like microservices. It validates the effectiveness of your test suite by injecting mutations (small code changes) into the code exercised by your tests and checking if your tests fail as a result.

    Key Use Cases:

    • Validating test suite quality beyond simple code coverage.
    • Aiding the Test-Driven Development (TDD) process.
    • Acting as a quality gate in Continuous Integration (CI) pipelines.

    Limitations:

    • Not recommended for very large Go modules, as execution times can extend to several hours.
  2. Core features of Gremlins

    main

    Gremlins provides several capabilities for mutation testing in Go:

    • Mutant Discovery: Automatically discovers mutant candidates and executes relevant tests.
    • Efficiency: Only tests mutants that are actually covered by existing tests.
    • Incremental Testing: Supports testing mutants only within PR (Pull Request) changes.
    • Mutant Types: Supports five distinct types of mutants.
    • Configuration: Uses YAML-based configuration files.
    • CI Integration: Designed to run as a quality gate in CI environments.
  3. Understand Invert bitwise assignments mutation

    main
    The Invert bitwise assignments mutation performs inversions on basic bitwise operations. It targets assignment operators where the result of the operation between two operands is assigned back to the left operand. This mutation helps verify if your tests are sensitive to incorrect bitwise logic by swapping the intended operator with an alternative one.
  4. Invert loop control mutations

    main

    The Invert loop control mutation type targets loop control operations by swapping their behavior. This is used to test if your test suite can detect when the flow of a loop is incorrectly altered. Specifically, it transforms continue statements into break statements and vice versa.

    // Original
    for i := 0; i < 3; i++ {
        continue
    }
    
    // Mutated
    for i := 0; i < 3; i++ {
        break
    }
  5. Understand Integration Mode behavior

    main

    When running in Integration mode, Gremlins is significantly more CPU-intensive. To compensate and prevent system exhaustion, Gremlins automatically halves the effective values for both workers and test CPU.

    For example, if you explicitly configure --workers 4, Gremlins will effectively run with only 2 workers when in integration mode. The same halving logic applies to the --test-cpu setting.

  6. Invert logical operators mutation

    main

    The Invert logical mutation type targets logical operators in Go code, swapping them for their opposites to test the robustness of test suites against logical errors.

    Specifically, it performs the following transformations:

    • Replaces && (logical AND) with || (logical OR).
    • Replaces || (logical OR) with && (logical AND).
    // Original
    a := true && false
    
    // Mutated
    a := true || false
  7. Understand the Remove self-assignments mutation

    main

    The Remove self-assignments mutation tests the robustness of your code by replacing compound assignment operators with simple assignment operators. Instead of performing an operation between the current value and a new value (e.g., a += 2), the mutation performs a trivial assignment (e.g., a = 2). This helps identify if your tests actually verify that the arithmetic or bitwise operation occurred, rather than just checking that the variable was updated.

    // Original
    a := 1
    a += 2
    
    // Mutated
    a := 1
    a = 2
  8. Understand the Invert bitwise mutation

    main

    The Invert bitwise mutation performs inversions on basic bitwise operations. This mutation tests the robustness of your code by swapping bitwise operators with different ones to see if your tests can detect the logic change.

    Mutation Mapping

    Original OperatorMutated Operator
    & (AND)| (OR)
    | (OR)& (AND)
    ^ (XOR)& (AND)
    &^ (AND NOT)& (AND)
    >> (Right Shift)<< (Left Shift)
    << (Left Shift)>> (Right Shift)
  9. Use Arithmetic base mutations

    main

    The Arithmetic base mutation set performs inversions on basic arithmetic operations to test the robustness of your code's logic. When this mutation is applied, the following transformations occur:

    OriginalMutated
    +-
    -+
    */
    /*
    %*

    This is useful for ensuring that your unit tests are sensitive enough to detect incorrect mathematical logic.

    // Original code
    a := 1 + 2
    
    // Mutated code (Arithmetic base)
    a := 1 - 2
  10. Gremlins versioning and stability warning

    main

    Gremlins is currently in 0.x.x release status. Users should be aware of the following SemVer implications:

    • No backward compatibility guarantee: Configuration flags and configuration file schemas may change between minor releases.
    • Maintenance policy: Only the current minor release is maintained. For example, if the current version is v0.2.0, patch releases will not be provided for the v0.1.0 line.
    • Future stability: Backward compatibility guarantees will begin once the project reaches 1.x.x release.