CLI Testing Patterns
Comprehensive testing strategies for CLI applications using industry-standard testing frameworks. Covers command execution testing, exit code validation, output verification, interactive prompt testing, and integration testing patterns.
Instructions
When Testing Node.js CLI Tools
-
Use Jest for testing CLI commands
- Import
child_process.execSyncfor command execution - Create helper function to run CLI and capture output
- Test exit codes, stdout, stderr separately
- Handle both success and error cases
- Import
-
Test Structure
- Set up CLI path relative to test location
- Create
runCLI()helper that returns{stdout, stderr, code} - Use try-catch to handle non-zero exit codes
- Test common scenarios: version, help, unknown commands
-
What to Test
- Command execution with various argument combinations
- Exit code validation (0 for success, non-zero for errors)
- Output content (stdout) validation
- Error messages (stderr) validation
- Configuration file handling
- Interactive prompts (with mocked input)
When Testing Python CLI Tools
-
Use pytest with Click.testing.CliRunner
- Import
CliRunnerfromclick.testing - Create runner fixture for reusable test setup
- Invoke commands with
runner.invoke(cli, ['args']) - Check
result.exit_codeandresult.output
- Import
-
Test Structure
- Create pytest fixture for CliRunner instance
- Use
runner.invoke()to execute CLI commands - Access results through
resultobject - Simulate interactive input with
input='responses\n'
-
What to Test
- Command invocation with various arguments
- Exit code validation
- Output content verification
- Error handling and messages
- Interactive prompt responses
- Configuration handling
Exit Code Testing Patterns
Standard Exit Codes:
0- Success1- General error2- Misuse of command (invalid arguments)126- Command cannot execute127- Command not found128+N- Fatal error signal N
Testing Strategy:
- Always test both success (0) and failure (non-zero) cases
- Verify specific exit codes for different error conditions
- Test argument validation returns appropriate codes
- Ensure help/version return 0 (success)
Output Validation Patterns
Content Testing:
- Check for presence of key text in output
- Validate format (JSON, YAML, tables)
- Test color/formatting codes (if applicable)
- Verify error messages are user-friendly
Best Practices:
- Use
.toContain()for flexible matching (Jest) - Use
in result.outputfor Python tests - Test both positive and negative cases
- Validate complete workflows (multi-command)
Templates
Use these templates for CLI testing:
Node.js/Jest Templates
templates/jest-cli-test.ts- Complete Jest test suite with execSynctemplates/jest-config-test.ts- Configuration file testingtemplates/jest-integration-test.ts- Multi-command integration tests
Python/Pytest Templates
templates/pytest-click-test.py- Click.testing.CliRunner teststemplates/pytest-fixtures.py- Reusable pytest fixturestemplates/pytest-integration-test.py- Integration test patterns
Test Utilities
templates/test-helpers.ts- Node.js test helper functionstemplates/test-helpers.py- Python test helper functions
Scripts
Use these scripts for test setup and execution:
scripts/setup-jest-testing.sh- Install Jest and configure for CLI testingscripts/setup-pytest-testing.sh- Install pytest and Click testing dependenciesscripts/run-cli-tests.sh- Execute all CLI tests with coveragescripts/validate-test-coverage.sh- Check test coverage thresholds
Examples
See complete examples in the examples/ directory:
examples/jest-basic/- Basic Jest CLI testing setupexamples/jest-advanced/- Advanced Jest patterns with mockingexamples/pytest-click/- Click.testing.CliRunner examplesexamples/integration-testing/- Full integration test suitesexamples/exit-code-testing/- Exit code validation patterns
Requirements
Node.js Testing:
- Jest 29.x or later
- TypeScript support (ts-jest)
- Node.js 16+
Python Testing:
- pytest 7.x or later
- Click 8.x or later
- Python 3.8+
Both:
- Test coverage reporting tools
- CI/CD integration support
- Mock/stub capabilities for external dependencies
Best Practices
- Test in Isolation - Each test should be independent
- Mock External Dependencies - Don't make real API calls or file system changes
- Test Error Paths - Test failures as thoroughly as successes
- Use Fixtures - Share setup code across tests
- Clear Test Names - Name tests to describe what they validate
- Fast Execution - Keep tests fast for rapid feedback
- Coverage Goals - Aim for 80%+ code coverage
- Integration Tests - Test complete workflows, not just units
Purpose: Standardize CLI testing across Node.js and Python projects Load when: Writing tests for CLI tools, validating command execution, testing exit codes