This directory contains automated tests for the OSA (Open Source Automation) CLI scripts.
Tests use a combination of techniques to avoid actual system modifications:
- Mocking - Critical system commands (rm, ln, mv) are mocked to capture calls instead of executing
- Temporary Directories - File operations use isolated temp directories, not real home or system paths
- Dry-Run Mode - Tests verify the CLI's
--dry-runflag works correctly - Function Isolation - Individual functions are tested with controlled inputs and mocked dependencies
# Install test dependencies
brew install bats-core
# Or on Linux:
sudo apt-get install batscd /Users/fre/dev/osa
bats tests/bats tests/test_cli_args.bats
bats tests/test_clean_function.batsbats --verbose tests/# Using entr (brew install entr)
ls tests/*.bats | entr bats tests/test_cli_args.bats- Argument parsing, flag handling, action selectiontest_clean_function.bats- clean_all() function with mocked filesystemtest_component_execution.bats- Component registration and executionfixtures/- Test data and helper scriptshelpers.zsh- Shared test utilities and mocks
Each test file includes:
- Setup - Initialize test environment, create temp directories, mock commands
- Teardown - Clean up temp files, restore original commands
- Tests - Individual test cases with clear naming and assertions
@test "should parse --clean flag" {
# Arrange
local result
# Act
result=$( is_flag_set "--clean" "--verbose --clean --minimal" )
# Assert
[[ "$result" == "true" ]]
}To prevent destructive operations, these commands are mocked in tests:
rm- Logs deletion calls instead of deletingln- Logs symlink creation instead of creatingmv- Logs move operations instead of movingmkdir- Logs directory creationreadlink- Returns test data instead of reading actual symlinks
# In tests/helpers.zsh
mock_rm() {
echo "MOCK: rm $@" >> "$TEST_LOG"
return 0
}
# Use in test
@test "should remove symlinks safely" {
alias rm=mock_rm
# Run function that calls rm
clean_all true
# Verify calls
grep "MOCK: rm /home/user/.osa" "$TEST_LOG"
}Tests verify these safety mechanisms:
- Home directory validation - Rejects if $HOME is "/" or unset
- Symlink target validation - Only removes OSA symlinks, not user files
- Confirmation skipping - --unsafe flag bypasses prompts
- Dry-run prevention - --clean rejects --dry-run combination
- Argument order independence - Flags work in any order
To run tests in CI/CD pipelines:
#!/bin/zsh
set -e
# Install bats
brew install bats-core 2>/dev/null || apt-get install -y bats
# Run tests with exit code
bats tests/ --tap
# Exit with test result code
exit $?- Create new
.batsfile intests/directory - Source helpers and setup mocks in the file header
- Use
@test "description"for each test case - Follow AAA pattern: Arrange, Act, Assert
- Use assertions from helpers.bash
- Clean up any temp files in
@test teardownblock
- Tests don't actually create/remove symlinks (they're mocked)
- Network operations (curl for mise installer) are stubbed
- Platform detection can be mocked for cross-platform testing
- Some integration tests require manual verification
To debug a failing test:
# Run single test with debugging
bats tests/test_clean_function.bats --verbose --filter "should remove symlinks"
# Add set -x for shell tracing
bats -x tests/test_cli_args.batsTo inspect test environment:
# Source the test helpers in an interactive shell
source tests/helpers.bash
source /Users/fre/dev/osa/osa-cli.zsh
# Call functions manually
should_clean=true
unsafe_mode=true
clean_all "$unsafe_mode"