Skip to content

Latest commit

 

History

History
151 lines (113 loc) · 3.34 KB

File metadata and controls

151 lines (113 loc) · 3.34 KB

Testing Guide

Overview

Dev-Control uses bats-core for testing. Tests are organised by component:

tests/
├── dc.bats              # Integration tests for the `dc` entrypoint (help, --version, status JSON)
├── plugin.bats          # Tests for plugin discovery via `dc plugin list/info`
├── run_tests.sh         # Test runner script (bootstraps bats if missing)
├── lib/                 # Unit tests for the shared library modules
│   ├── cli.bats         # scripts/lib/cli.sh + scripts/lib/validation.sh
│   ├── config.bats      # scripts/lib/config.sh (YAML parser, dc_config, dc_config_set)
│   ├── git_utils.bats   # scripts/lib/git/utils.sh (parse_github_url, branch/remote helpers, ...)
│   └── output.bats      # scripts/lib/output.sh (out, verbose, json_field, parse_output_flags)
└── test_helper/         # bats plugins (auto-installed by run_tests.sh)
    ├── bats/
    ├── bats-support/
    └── bats-assert/

Running Tests

All Tests

./tests/run_tests.sh

Specific Tests

# Library tests only
./tests/run_tests.sh lib/

# Specific test file
./tests/run_tests.sh dc.bats

# Specific test by name
bats --filter "dc --help" tests/dc.bats

With Coverage

# Install kcov first
sudo apt install kcov

# Run with coverage
kcov --include-path=./scripts coverage/ ./tests/run_tests.sh

Writing Tests

Basic Structure

#!/usr/bin/env bats

load 'test_helper/bats-support/load'
load 'test_helper/bats-assert/load'

setup() {
    # Runs before each test
    source "$BATS_TEST_DIRNAME/../scripts/lib/cli.sh"
}

teardown() {
    # Runs after each test
    rm -rf "$TEST_TEMP_DIR"
}

@test "description of what is being tested" {
    run my_function "arg1" "arg2"
    assert_success
    assert_output "expected output"
}

Common Assertions

# Status assertions
assert_success           # Exit code 0
assert_failure           # Non-zero exit code

# Output assertions
assert_output "exact"    # Exact match
assert_output --partial "contains"  # Substring
assert_output --regexp "pattern.*"  # Regex

# Comparison
assert_equal "$actual" "expected"

# File assertions
assert [ -f "$file" ]    # File exists
assert [ -d "$dir" ]     # Directory exists

Testing Functions

@test "to_slug lowercases and hyphenates" {
    result=$(to_slug "My Project Name")
    assert_equal "$result" "my-project-name"
}

Testing Commands

@test "dc init creates config" {
    local temp_dir=$(mktemp -d)
    cd "$temp_dir"
    git init --quiet
    
    run "$DC" init
    assert_success
    assert [ -f ".dc-init.yaml" ]
    
    rm -rf "$temp_dir"
}

CI Integration

Tests run automatically on push via GitHub Actions:

# .github/workflows/test.yml
name: Tests

on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Run tests
        run: ./tests/run_tests.sh

Best Practices

  1. Isolate tests: Use temp directories, reset globals
  2. Test one thing: Each test should verify a single behaviour
  3. Use descriptive names: @test "dc init with --licence creates LICENCE"
  4. Clean up: Always remove temp files in teardown
  5. Test edge cases: Empty inputs, missing files, invalid args