This document describes the testing infrastructure for phpvm and how to run tests.
phpvm uses a multi-layered testing approach:
- Built-in Tests - Self-tests within phpvm.sh
- BATS Tests - Comprehensive test suite using BATS framework
- ShellCheck - Static analysis and linting
- shfmt - Code formatting verification
- CI/CD - Automated testing on multiple platforms
# Install all development dependencies
make install
# Or install individually:
brew install shellcheck shfmt bats-core # macOS
sudo apt-get install shellcheck bats # Debian/Ubuntu# Run all checks (recommended)
make check
# Run individual test suites
make test # Built-in tests
make test-bats # BATS test suite
make lint # ShellCheck analysis
make format-check # Formatting verification
# Run all tests
make test-allphpvm includes comprehensive self-tests that verify core functionality:
./phpvm.sh testWhat it tests:
- Input sanitization
- Version validation
- Directory creation
- File operations
- PATH management
- Environment detection
- Package manager detection
Advantages:
- No external dependencies
- Runs in test mode (no system changes)
- Fast execution
- Built into the tool
BATS (Bash Automated Testing System) provides comprehensive integration testing.
Location: tests/ directory
Test files:
tests/test_helper.bash- Setup, teardown, and helper functionstests/01_core.bats- Core functionality teststests/02_features.bats- Placeholder feature teststests/03_error_handling.bats- Error handling and edge cases
Run BATS tests:
# Run all BATS tests
make test-bats
# Or directly with BATS
bats tests/
# Run specific test file
bats tests/01_core.bats
# Run with verbose output
bats -t tests/Writing BATS tests:
#!/usr/bin/env bats
load test_helper
@test "description of what you're testing" {
run command_to_test
[ "$status" -eq 0 ]
[[ "$output" =~ "expected output" ]]
}ShellCheck analyzes shell scripts for common issues, security problems, and style violations.
Configuration: .shellcheckrc
Run linting:
# Run ShellCheck
make lint
# Or directly
shellcheck phpvm.sh install.shWhat it checks:
- Syntax errors
- Semantic problems
- Security issues (command injection, etc.)
- Portability issues
- Style violations
shfmt formats shell scripts consistently.
Configuration: Follows .editorconfig (4-space indentation)
Run formatting:
# Format code
make format
# Check formatting (CI mode)
make format-check
# Or directly
shfmt -w -i 4 -sr phpvm.sh install.sh # Format
shfmt -d -i 4 -sr phpvm.sh install.sh # Check onlyThe Makefile provides convenient shortcuts for all testing operations:
| Command | Description |
|---|---|
make help |
Display all available commands |
make install |
Install development dependencies |
make install-hooks |
Install git pre-commit hooks |
make lint |
Run ShellCheck linter |
make format |
Format code with shfmt |
make format-check |
Check formatting (CI) |
make test |
Run built-in tests |
make test-bats |
Run BATS test suite |
make test-all |
Run all tests |
make check |
Run all checks |
make clean |
Remove temporary files |
make release |
Prepare for release |
Install pre-commit hooks to automatically run checks before each commit:
make install-hooksWhat the hook does:
- Checks code formatting
- Runs linter (ShellCheck)
- Prevents commit if checks fail
Skip hooks temporarily:
git commit --no-verifyphpvm uses GitHub Actions for automated testing:
Workflows:
- test.yml - Main test suite (syntax, core tests, multi-platform)
- security-test.yml - Security analysis
- release.yml - Release automation
Platforms tested:
- Ubuntu (latest)
- macOS (latest)
- Multiple Linux distributions (Debian, Fedora, Arch, Alpine, Rocky, Alma)
Package managers tested:
- Homebrew (macOS)
- apt (Debian/Ubuntu)
- dnf (Fedora/RHEL)
- yum (CentOS/RHEL)
- pacman (Arch)
# Simulate CI checks
make check
# Or step by step
make lint
make format-check
make test
make test-batsBuilt-in tests: 14+ test functions covering:
- β Input validation and sanitization
- β Version format validation
- β Directory operations
- β File operations (atomic writes)
- β PATH management
- β Version switching
- β Deactivation
- β .phpvmrc detection
BATS tests: 40+ test cases covering:
- β Core functionality
- β Command-line interface
- β Error handling
- β Edge cases
- β Placeholder features
- β Input validation
- β File system operations
When adding new features, always add tests:
- Add built-in test in
phpvm.shrun_tests()function - Add BATS test in appropriate
tests/*.batsfile - Update this document with new test information
Example - Adding a BATS test:
# tests/01_core.bats
@test "new feature works correctly" {
# Setup
local test_input="8.1"
# Execute
run new_function "$test_input"
# Assert
[ "$status" -eq 0 ]
[ "$output" = "expected result" ]
}- Test one thing at a time - Each test should verify a single behavior
- Use descriptive names - Test names should clearly describe what's being tested
- Test error cases - Don't just test the happy path
- Use setup/teardown - Clean up after tests
- Make tests independent - Tests shouldn't depend on each other
- Group related tests - Use separate files for different concerns
- Order logically - Run fast tests first
- Use helpers - Extract common setup into helper functions
- Document edge cases - Add comments for non-obvious test cases
# Quick feedback loop
make lint && make test
# Before committing
make check
# Full test suite
make test-all# Install BATS
./install-bats.sh
# Or via package manager
brew install bats-core # macOS
sudo apt-get install bats # Debian/Ubuntu# Install ShellCheck
brew install shellcheck # macOS
sudo apt-get install shellcheck # Debian/Ubuntu
sudo dnf install ShellCheck # Fedora/RHEL# Install shfmt
brew install shfmt # macOS
# Or with Go
GO111MODULE=on go install mvdan.cc/sh/v3/cmd/shfmt@latest- Check that you're using the same environment
- Verify all dependencies are installed
- Check for platform-specific issues
- Review CI logs for specific error messages
# Fix formatting
make format
# Fix linting issues
make lint
# Re-run checks
make checkApproximate execution times on modern hardware:
- Built-in tests: ~2-5 seconds
- BATS tests: ~5-10 seconds
- ShellCheck: ~1-2 seconds
- Format check: ~1 second
- Full suite: ~10-20 seconds
- Run fast tests first (linting, formatting)
- Use test mode to avoid system changes
- Mock external dependencies
- Parallelize when possible (BATS supports
-jflag)
Planned testing improvements:
- Code coverage reporting (using kcov)
- Performance benchmarking
- Mutation testing
- Fuzz testing for input validation
- Integration tests with real PHP installations
- Cross-platform compatibility matrix
- Stress testing (many versions, rapid switches)
When contributing to phpvm:
- Write tests first (TDD approach)
- Ensure all tests pass (
make check) - Add tests for bug fixes
- Document test scenarios
- Follow existing test patterns
Last Updated: January 15, 2026 Test Suite Version: 2.0 Total Tests: 50+ test cases