Skip to content

Repository files navigation

speq - Test Queue Distribution Tool

A universal test runner that distributes tests across multiple workers for parallel execution.

Features

  • ✅ Parallel test execution with multiple workers
  • ✅ RSpec support (by-file strategy)
  • ✅ In-memory queue for local execution
  • ✅ Simple CLI interface
  • 🚧 GitHub Actions integration (planned)
  • 🚧 Jest and pytest support (planned)

Installation

Prerequisites

  • Go 1.23 or later
  • RSpec (for running Ruby tests)

Build from source

go build -o speq .

Or using mise:

mise install
mise exec -- go build -o speq .

Usage

Running tests in parallel

# Run with 4 workers (default)
./speq test spec/

# Run with custom number of workers
./speq test --workers 8 spec/

# Run with custom batch size
./speq test --workers 4 --batch-size 10 spec/

Generating a test manifest

# Generate manifest for spec/ directory
./speq manifest spec/

# Custom output file
./speq manifest --output my-manifest.json spec/

Global options

--config string      # Config file (default: ./speq.yml)
--strategy string    # Distribution strategy: by-file (default)
--batch-size int     # Tests per batch (default: 7)

Using as a GitHub Actions Composite Action

speq can be used as a reusable GitHub Actions composite action in your workflows.

Usage in Public Repositories

name: RSpec Tests

on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Run tests with speq
        uses: ryotoya/speq@main
        with:
          workers: 4
          batch-size: 7
          test-directory: spec
          ruby-version: '3.3'

Usage in Private Repositories

For private repositories, you need to checkout the speq action using a Personal Access Token (PAT):

name: RSpec Tests

on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      # Checkout speq action from private repository
      - name: Checkout speq action
        uses: actions/checkout@v4
        with:
          repository: ryotoya/speq
          token: ${{ secrets.GH_PAT }}  # PAT with repo scope
          path: .github/actions/speq

      # Use the checked-out action
      - name: Run tests with speq
        uses: ./.github/actions/speq
        with:
          workers: 4
          batch-size: 7
          test-directory: spec
          ruby-version: '3.3'

Action Inputs

Input Description Required Default
workers Number of workers to run in parallel No 4
batch-size Number of tests to pull from queue at a time No 7
test-directory Directory containing test files No spec
ruby-version Ruby version to use No 3.3
go-version Go version for building speq No 1.23

Setting up Personal Access Token (PAT)

For private repositories, you need to create a PAT:

  1. Go to GitHub Settings → Developer settings → Personal access tokens → Tokens (classic)
  2. Generate new token with repo scope
  3. Add the token as a secret in your repository:
    • Repository Settings → Secrets and variables → Actions
    • New repository secret: GH_PAT = your token value

Example with Bundler

If your project has a Gemfile, the action will automatically run bundle install:

- name: Run tests with speq
  uses: ./.github/actions/speq
  with:
    workers: 8
    batch-size: 10
    test-directory: spec

How it works

Local Execution

┌─────────────┐
│   Queue     │  ← In-memory queue manages test distribution
│ (LocalQueue)│
└──────┬──────┘
       │
       ├─────────┬─────────┬─────────┐
       ↓         ↓         ↓         ↓
  ┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐
  │Worker 0│ │Worker 1│ │Worker 2│ │Worker 3│
  └────────┘ └────────┘ └────────┘ └────────┘
  1. Discovery: Parse test directory to find all *_spec.rb files
  2. Distribution: Queue distributes tests in batches to workers
  3. Execution: Each worker executes tests using RSpec
  4. Aggregation: Results are collected and displayed

Project Structure

speq/
├── cmd/                    # CLI commands
│   ├── root.go            # Root command and config
│   ├── manifest.go        # Generate test manifest
│   └── test.go            # Run tests command
├── internal/
│   ├── queue/             # Queue implementations
│   │   ├── queue.go       # Queue interface
│   │   └── local.go       # In-memory local queue
│   ├── parser/
│   │   └── rspec.go       # RSpec test parser
│   ├── worker/
│   │   ├── worker.go      # Worker implementation
│   │   └── executor.go    # RSpec test executor
│   └── reporter/
│       ├── reporter.go    # Result aggregation
│       └── terminal.go    # Terminal output
└── pkg/protocol/
    └── messages.go        # Data structures

Development Status

✅ Implemented (MVP - Local Execution)

  • Project setup and structure
  • Data structures (TestCase, TestResult, TestManifest)
  • RSpec parser (by-file strategy)
  • Local in-memory queue
  • Worker implementation
  • RSpec executor with JSON output parsing
  • Result aggregation and reporting
  • CLI commands (test, manifest)
  • Parallel execution with goroutines

🚧 Planned

  • GitHub Actions integration (file-based queue)
  • Report command for result aggregation
  • Jest support
  • pytest support
  • by-test distribution strategy
  • Automatic retry of flaky tests
  • Historical data-based optimization

Configuration

Create a speq.yml file in your project root:

version: 1

# Test framework
framework: rspec

# Distribution strategy
strategy: by-file  # or by-test (future)

# Batch size
batch_size: 7

# Test directory
test_dir: spec

Example Output

🚀 Starting speq with 4 workers
   Test directory: spec/
   Strategy: by-file
   Batch size: 7

📋 Discovered 24 test files

[Worker 0] ✓ spec/models/user_spec.rb (0.45s)
[Worker 1] ✓ spec/models/post_spec.rb (0.32s)
[Worker 2] ✓ spec/controllers/users_controller_spec.rb (0.78s)
[Worker 3] ✓ spec/services/auth_service_spec.rb (0.56s)
...

============================================================
Test Results Summary
============================================================

✓ Passed:  23
✗ Failed:  1
- Skipped: 0

Total:     24 tests
Duration:  5.32s
Workers:   4

Worker Statistics:
  Worker 0: 6 tests in 4.23s
  Worker 1: 6 tests in 4.87s
  Worker 2: 6 tests in 5.12s
  Worker 3: 6 tests in 4.56s

License

MIT

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages