- 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> |
||
---|---|---|
.. | ||
fixtures | ||
integration | ||
support | ||
unit | ||
examples.txt | ||
README.md | ||
spec_helper.rb |
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 frameworksimplecov
- Code coverage reportingfactory_bot
- Test data factorieswebmock
- 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 reportcoverage/coverage.json
- JSON data- Console summary during test runs
Troubleshooting
Common Issues
- Docker containers not starting: Check Docker daemon is running and ports are available
- Permission errors: Ensure test script is executable (
chmod +x bin/test
) - Bundle errors: Run
bundle install
in theapp
directory - 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
- Isolation: Each test should be independent and clean up after itself
- Descriptive Names: Use clear, descriptive test names and descriptions
- Mock External Dependencies: Use mocks for Docker API calls in unit tests
- Test Error Conditions: Include tests for error handling and edge cases
- Coverage: Aim for high test coverage, especially for critical backup logic
- Fast Feedback: Keep unit tests fast for quick development feedback