baktainer/app/spec
James Paterni 67bea93bb2
Some checks are pending
Test and Build Docker Image / test (push) Waiting to run
Test and Build Docker Image / build (push) Blocked by required conditions
Fix timestamp-dependent test failures by using dynamic patterns
- Replace hardcoded timestamps with regex patterns in integration tests
- Use dynamic file discovery instead of exact filenames in unit tests
- Change timestamp pattern from specific values to \d{10} regex for 10-digit unix timestamps
- Update backup file assertions to use Dir.glob and pattern matching
- Ensure tests are robust across different execution environments and times

This resolves intermittent test failures caused by timestamp variations
between test runs and different execution contexts.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-13 23:19:12 -04:00
..
fixtures Add comprehensive RSpec testing infrastructure and enhance CI/CD pipeline 2025-07-13 23:12:59 -04:00
integration Fix timestamp-dependent test failures by using dynamic patterns 2025-07-13 23:19:12 -04:00
support Add comprehensive RSpec testing infrastructure and enhance CI/CD pipeline 2025-07-13 23:12:59 -04:00
unit Fix timestamp-dependent test failures by using dynamic patterns 2025-07-13 23:19:12 -04:00
examples.txt Add comprehensive RSpec testing infrastructure and enhance CI/CD pipeline 2025-07-13 23:12:59 -04:00
README.md Add comprehensive RSpec testing infrastructure and enhance CI/CD pipeline 2025-07-13 23:12:59 -04:00
spec_helper.rb Add comprehensive RSpec testing infrastructure and enhance CI/CD pipeline 2025-07-13 23:12:59 -04:00

Baktainer Testing Guide

This directory contains the complete test suite for Baktainer, including unit tests, integration tests, and testing infrastructure.

Test Structure

spec/
├── unit/                   # Unit tests for individual components
│   ├── backup_command_spec.rb   # Tests for backup command generation
│   ├── container_spec.rb        # Tests for container management
│   └── baktainer_spec.rb        # Tests for main runner class
├── integration/           # Integration tests with real containers
│   └── backup_workflow_spec.rb  # End-to-end backup workflow tests
├── fixtures/             # Test data and configuration
│   ├── docker-compose.test.yml  # Test database containers
│   └── factories.rb             # Test data factories
├── support/              # Test support files
│   └── coverage.rb              # Coverage configuration
├── spec_helper.rb        # Main test configuration
└── README.md            # This file

Running Tests

Quick Start

# Run unit tests only (fast)
cd app && bundle exec rspec spec/unit/

# Run all tests with coverage
cd app && COVERAGE=true bundle exec rspec

# Use the test runner script
cd app && bin/test --all --coverage

Test Runner Script

The bin/test script provides a convenient way to run tests with various options:

# Run unit tests (default)
bin/test

# Run integration tests with container setup
bin/test --integration --setup --cleanup

# Run all tests with coverage
bin/test --all --coverage

# Show help
bin/test --help

Using Rake Tasks

# Install dependencies
rake install

# Run unit tests
rake spec

# Run integration tests
rake integration

# Run all tests
rake spec_all

# Run tests with coverage
rake coverage

# Full test suite with setup/cleanup
rake test_full

# Open coverage report
rake coverage_report

Test Categories

Unit Tests

Unit tests focus on individual components in isolation:

  • Backup Command Tests (backup_command_spec.rb): Test command generation for different database engines
  • Container Tests (container_spec.rb): Test container discovery, validation, and backup orchestration
  • Runner Tests (baktainer_spec.rb): Test the main application runner, thread pool, and scheduling

Unit tests use mocks and stubs to isolate functionality and run quickly without external dependencies.

Integration Tests

Integration tests validate the complete backup workflow with real Docker containers:

  • Container Discovery: Test finding containers with backup labels
  • Database Backups: Test actual backup creation for PostgreSQL, MySQL, and SQLite
  • Error Handling: Test graceful handling of failures and edge cases
  • Concurrent Execution: Test thread pool and concurrent backup execution

Integration tests require Docker and may take longer to run.

Test Environment Setup

Dependencies

Install test dependencies:

cd app
bundle install

Required gems for testing:

  • rspec - Testing framework
  • simplecov - Code coverage reporting
  • factory_bot - Test data factories
  • webmock - HTTP request stubbing

Test Database Containers

Integration tests use Docker containers defined in spec/fixtures/docker-compose.test.yml:

  • PostgreSQL container with test database
  • MySQL container with test database
  • SQLite container with test database file
  • Control container without backup labels

Start test containers:

cd app
docker-compose -f spec/fixtures/docker-compose.test.yml up -d

Stop test containers:

cd app
docker-compose -f spec/fixtures/docker-compose.test.yml down -v

Test Configuration

RSpec Configuration (.rspec)

--require spec_helper
--format documentation
--color
--profile 10
--order random

Coverage Configuration

Test coverage is configured in spec/support/coverage.rb:

  • Minimum coverage: 80%
  • Minimum per-file coverage: 70%
  • HTML and console output formats
  • Branch coverage tracking (Ruby 2.5+)
  • Coverage tracking over time

Enable coverage:

COVERAGE=true bundle exec rspec

Environment Variables

Tests clean up environment variables between runs and use temporary directories for backup files.

Writing Tests

Unit Test Example

RSpec.describe Baktainer::BackupCommand do
  describe '.postgres' do
    it 'generates correct pg_dump command' do
      result = described_class.postgres(login: 'user', password: 'pass', database: 'testdb')
      
      expect(result).to be_a(Hash)
      expect(result[:env]).to eq(['PGPASSWORD=pass'])
      expect(result[:cmd]).to eq(['pg_dump', '-U', 'user', '-d', 'testdb'])
    end
  end
end

Integration Test Example

RSpec.describe 'PostgreSQL Backup', :integration do
  let(:postgres_container) do
    containers = Baktainer::Containers.find_all
    containers.find { |c| c.engine == 'postgres' }
  end

  it 'creates a valid PostgreSQL backup' do
    postgres_container.backup
    
    backup_files = Dir.glob(File.join(test_backup_dir, '**', '*.sql'))
    expect(backup_files).not_to be_empty
    
    backup_content = File.read(backup_files.first)
    expect(backup_content).to include('PostgreSQL database dump')
  end
end

Test Helpers

Use test helpers defined in spec_helper.rb:

# Create mock Docker container
container = mock_docker_container(labels)

# Create temporary backup directory
test_dir = create_test_backup_dir

# Set environment variables for test
with_env('BT_BACKUP_DIR' => test_dir) do
  # test code
end

Continuous Integration

GitHub Actions

Add to .github/workflows/test.yml:

name: Tests
on: [push, pull_request]
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: ruby/setup-ruby@v1
        with:
          ruby-version: 3.3
          bundler-cache: true
      - name: Run tests
        run: |
          cd app
          COVERAGE=true bundle exec rspec
      - name: Upload coverage
        uses: codecov/codecov-action@v3

Coverage Reporting

Coverage reports are generated in coverage/ directory:

  • coverage/index.html - HTML report
  • coverage/coverage.json - JSON data
  • Console summary during test runs

Troubleshooting

Common Issues

  1. Docker containers not starting: Check Docker daemon is running and ports are available
  2. Permission errors: Ensure test script is executable (chmod +x bin/test)
  3. Bundle errors: Run bundle install in the app directory
  4. Coverage not working: Set COVERAGE=true environment variable

Debugging Tests

# Run specific test file
bundle exec rspec spec/unit/container_spec.rb

# Run specific test
bundle exec rspec spec/unit/container_spec.rb:45

# Run with debug output
bundle exec rspec --format documentation --backtrace

# Run integration tests with container logs
docker-compose -f spec/fixtures/docker-compose.test.yml logs

Performance

  • Unit tests should complete in under 10 seconds
  • Integration tests may take 30-60 seconds including container startup
  • Use bin/test --unit for quick feedback during development
  • Run full test suite before committing changes

Best Practices

  1. Isolation: Each test should be independent and clean up after itself
  2. Descriptive Names: Use clear, descriptive test names and descriptions
  3. Mock External Dependencies: Use mocks for Docker API calls in unit tests
  4. Test Error Conditions: Include tests for error handling and edge cases
  5. Coverage: Aim for high test coverage, especially for critical backup logic
  6. Fast Feedback: Keep unit tests fast for quick development feedback