baktainer/app/spec/README.md

306 lines
7.6 KiB
Markdown
Raw Normal View History

# 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
```bash
# 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:
```bash
# 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
```bash
# 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:
```bash
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:
```bash
cd app
docker-compose -f spec/fixtures/docker-compose.test.yml up -d
```
Stop test containers:
```bash
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:
```bash
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
```ruby
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
```ruby
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`:
```ruby
# 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`:
```yaml
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
```bash
# 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