This repository contains Git hooks that automatically run PHP Unit tests before commits to ensure code quality and maintain development standards in your PHP/Laravel projects.
This tool acts as a quality gate at the commit level, preventing untested or breaking code from entering your repository. It provides:
- Early Detection: Catch failing tests immediately, before they reach your main branch
- Cleaner Git History: Every commit in your history has passed tests
- Team Protection: Prevents teammates from pulling broken code
- Development Discipline: Encourages writing and maintaining tests
- Faster Debugging: Test results are recorded with each commit for easy tracking
Think of it as a safety net - it's much easier to fix a failing test before you commit than to hunt down which commit broke the build later.
- pre-commit: Runs PHP Unit tests before allowing a commit. If tests fail, the commit is aborted.
- post-commit: Appends PHP Unit test results to the commit message for tracking purposes.
Run this command from your project's root directory:
curl -sSL https://raw.githubusercontent.com/mobilozophy/git-hooks-phpunit-test-on-commit/main/install.sh | bash -s -- --remote-installFrom your project's root directory:
# Clone the hooks repository
git clone https://github.com/mobilozophy/git-hooks-phpunit-test-on-commit.git .git-hooks-temp
# Install the hooks
./.git-hooks-temp/install.sh
# Clean up
rm -rf .git-hooks-temp# Download the repository as a zip
curl -L https://github.com/mobilozophy/git-hooks-phpunit-test-on-commit/archive/main.zip -o git-hooks.zip
# Extract and install
unzip git-hooks.zip
cd git-hooks-phpunit-test-on-commit-main
./install.sh
# Clean up
cd ..
rm -rf git-hooks-phpunit-test-on-commit-main git-hooks.zip- PHP project with Unit tests
- Laravel project with
php artisan test --testsuite=Unitcommand available - Git repository initialized in your project
- Unix-like system (Linux, macOS, WSL)
The pre-commit hook:
- Checks for skip-tests flags (see "Skipping Tests" section below)
- Temporarily stashes any unstaged changes
- Runs
php artisan test --testsuite=Unit - Prevents the commit if tests fail
- Restores any stashed changes
- Allows the commit if all tests pass
The post-commit hook:
- Automatically appends test results to your commit message
- Provides a record of which tests passed with each commit
- Helps maintain development history and debugging
- Individual Development: Perfect for personal projects and feature branches
- Small to Medium Teams: Ensures everyone commits working code
- Fast Test Suites: Works best when unit tests run in under 30 seconds
- TDD/BDD Workflows: Complements test-driven development practices
- Install on all developer machines for consistency
- Use with feature branches - let developers fix issues before merging
- Combine with CI/CD - this catches issues early, CI/CD provides comprehensive testing
- Document skip policies - make it clear when skipping tests is acceptable
- Test Suite Speed: Hook runs on every commit, so fast tests are crucial
- Only Unit Tests: Runs
--testsuite=Unitto avoid slow integration/feature tests - Stashing Strategy: Temporarily stashes unstaged changes to test only committed code
This tool complements (doesn't replace) your CI/CD pipeline:
| Git Hooks (This Tool) | CI/CD Pipeline |
|---|---|
| Runs on developer machine | Runs on dedicated servers |
| Fast unit tests only | Full test suite + integration tests |
| Prevents bad commits | Prevents bad deployments |
| Individual developer feedback | Team/deployment feedback |
| Works offline | Requires server infrastructure |
Use both together for maximum code quality!
There are several ways to skip tests when appropriate (e.g., documentation changes, quick fixes, WIP commits):
Include [skip-tests] or --skip-tests in your commit message:
git commit -m "Update documentation [skip-tests]"
git commit -m "Quick typo fix --skip-tests"
git commit -m "WIP: experimental feature [skip-tests]"Note: This method works best when using git commit -m directly in terminal.
SKIP_TESTS=true git commit -m "Your commit message"Note: This method is most reliable when using IDEs, GUI clients, or complex git operations.
In rare emergency situations, you can bypass ALL git hooks:
git commit --no-verify -m "Emergency fix - server down"Note: --no-verify bypasses ALL hooks, not just tests. The flag methods above are preferred as they only skip tests while maintaining other hook functionality.
✅ Good reasons to skip tests:
- Documentation-only changes
- README updates
- Configuration file changes
- Quick typo fixes
- Work-in-progress commits
- Emergency hotfixes (when server is down)
❌ Avoid skipping tests for:
- New features
- Bug fixes
- Code refactoring
- Database migrations
- API changes
To remove the hooks from your project:
# Remove the hook symlinks
rm .git/hooks/pre-commit .git/hooks/post-commit
# Remove the git-hooks directory if it exists
rm -rf git-hooksIf you encounter any issues with the Git hooks:
-
Permission Issues: Ensure hooks are executable
chmod +x .git/hooks/pre-commit .git/hooks/post-commit
-
Hook Not Found: Check that hooks exist in
.git/hooks/directoryls -la .git/hooks/
-
Test Command Fails: Ensure your project supports
php artisan test --testsuite=Unit# Test the command manually php artisan test --testsuite=Unit
-
Git Directory Issues: Make sure you're in the root of a Git repository
git status
# Normal commit (runs tests)
git commit -m "Add user authentication feature"
# Skip tests for documentation
git commit -m "Update API documentation [skip-tests]"
# Skip tests with environment variable
SKIP_TESTS=true git commit -m "Update composer dependencies"
# Emergency bypass (use sparingly)
git commit --no-verify -m "Hotfix: critical security patch"To modify which tests run, edit the pre-commit hook and change this line:
php artisan test --testsuite=Unit > test_output.txt 2>&1Examples:
# Run all tests (slower)
php artisan test > test_output.txt 2>&1
# Run specific test groups
php artisan test --group=unit,integration > test_output.txt 2>&1
# Run tests with different output format
php artisan test --testsuite=Unit --compact > test_output.txt 2>&1For teams, consider creating a shared configuration:
- Document your skip policies in your project's README
- Set team standards for when tests can be skipped
- Consider branch-specific rules (stricter on main/develop branches)
- Review test results in commit messages during code reviews
Found a bug or want to contribute? Visit the GitHub repository to report issues or submit pull requests.