mirror of
https://github.com/pnpm/action-setup.git
synced 2026-03-01 07:51:02 +08:00
* chore: add alignment standards for github config - Add .nvmrc file with Node.js 22 - Add PR template for consistent pull requests - Add issue templates for bug reports, feature requests, and tasks - Add standard labels via gh CLI (type, priority, status, area labels) * fix: resolve form-data security vulnerability Add pnpm override to force form-data>=4.0.4 which fixes GHSA-fjxv-7rqg-78g4 (unsafe random function for boundary). * chore: add .claude/settings.local.json to gitignore * feat: Add claude commands * fix: update pnpm version to 10.27.0 (valid release) * fix: update pnpm version from 9 to 10 in all workflows Update all workflow files to use pnpm version 10 to match the packageManager field in package.json (pnpm@10.27.0). This fixes the CI failure caused by version mismatch: - pr-check.yml: version 9 → 10, matrix 9.15.5 → 10.27.0 - build-and-test.yml: version 9 → 10 - security.yml: version 9 → 10 - test.yaml: all version references updated to 10.27.0 * fix: remove packageManager field to allow testing multiple pnpm versions The action tests multiple pnpm versions (9.x and 10.x). Having a packageManager field in package.json causes version mismatch errors when the workflow specifies a different version than packageManager. * fix: use exact pnpm version 10.27.0 in workflows The action validates that the version specified in workflows must match the packageManager field in package.json exactly. Update from version: 10 to version: 10.27.0 to match pnpm@10.27.0. * fix: use local action in ci.yml with explicit version Since packageManager was removed from package.json to allow testing multiple pnpm versions, ci.yml must now specify the version explicitly. Changed from using released @v4.0.0 to using ./ (local action) to test the current code. * fix: rename claude commands to use Windows-compatible filenames Windows doesn't allow colons in filenames. Changed from using colons (agents:action.md) to hyphens (agents-action.md) for cross-platform compatibility.
6.4 KiB
6.4 KiB
Quick: Test
Run the test suite for the GitHub Action.
What This Does
Executes all tests to verify the action works correctly.
Test Execution
Run All Tests
pnpm test
Runs:
- All unit tests
- All integration tests
- Reports results and coverage
Run Specific Tests
# Single test file
pnpm test -- inputs.test.ts
# Pattern matching
pnpm test -- --testNamePattern="install"
# Watch mode
pnpm test -- --watch
Coverage Report
pnpm test -- --coverage
Generates:
- Coverage summary
- Detailed report
- HTML coverage report (if configured)
Usage
Just ask:
- "Run tests"
- "Test the action"
- "Check test coverage"
Output Format
=== Test Results ===
PASS src/__tests__/inputs.test.ts
✓ should parse version input (5ms)
✓ should expand tilde in paths (3ms)
✓ should validate run_install YAML (12ms)
PASS src/__tests__/install-pnpm.test.ts
✓ should install specified version (45ms)
✓ should handle standalone mode (38ms)
Test Suites: 2 passed, 2 total
Tests: 5 passed, 5 total
Time: 2.5s
Coverage: 85% statements, 80% branches
Test Organization
Current test structure:
src/
__tests__/
inputs.test.ts # Input parsing tests
outputs.test.ts # Output setting tests
install-pnpm.test.ts # Installation tests
pnpm-install.test.ts # pnpm install tests
utils.test.ts # Utility function tests
__mocks__/
@actions/
core.ts # Mock @actions/core APIs
Coverage Goals
Target coverage:
- Statements: >80%
- Branches: >75%
- Functions: >80%
- Lines: >80%
Test Types
Unit Tests
Test individual functions in isolation:
describe('getInputs', () => {
it('should parse version input', () => {
// Test implementation
})
})
Integration Tests
Test feature workflows:
describe('installPnpm', () => {
it('should install and configure pnpm', async () => {
// Test full installation flow
})
})
Mock Tests
Test with mocked dependencies:
jest.mock('@actions/core')
it('should call setFailed on error', async () => {
// Test error handling
})
Common Test Scenarios
Input Validation
it('should accept valid version formats', () => {
expect(() => validateVersion('8')).not.toThrow()
expect(() => validateVersion('8.15.0')).not.toThrow()
})
it('should reject invalid versions', () => {
expect(() => validateVersion('invalid')).toThrow()
})
Error Handling
it('should fail gracefully on missing input', async () => {
const mockSetFailed = core.setFailed as jest.Mock
await expect(main()).rejects.toThrow()
expect(mockSetFailed).toHaveBeenCalled()
})
Output Setting
it('should set all outputs', () => {
const mockSetOutput = core.setOutput as jest.Mock
setOutputs(inputs)
expect(mockSetOutput).toHaveBeenCalledWith('dest', expect.any(String))
})
Debugging Tests
Run with Debug Output
# Enable debug logging
DEBUG=* pnpm test
# Node debug output
NODE_OPTIONS='--inspect' pnpm test
Focus on Single Test
// Use .only to run single test
it.only('should test specific case', () => {
// This test will run alone
})
Skip Tests
// Use .skip to skip a test
it.skip('not ready yet', () => {
// This test will be skipped
})
Test Failures
When Tests Fail
-
Read error message
Expected: "8.15.0" Received: undefined -
Check test code
- Is the test correct?
- Is the expectation valid?
-
Check implementation
- Does the code match expectation?
- Are there edge cases?
-
Debug
- Add console.log
- Use debugger
- Check mock setup
Common Issues
Mock not working:
// Ensure mock is before import
jest.mock('@actions/core')
import { getInputs } from '../inputs'
Async issues:
// Ensure async tests use await
it('should work', async () => {
await asyncFunction() // Don't forget await
})
State pollution:
// Clear mocks between tests
beforeEach(() => {
jest.clearAllMocks()
})
Test Coverage
View Coverage
# Generate coverage report
pnpm test -- --coverage
# Open HTML report (if generated)
open coverage/lcov-report/index.html
Improve Coverage
-
Identify gaps
- Check uncovered lines in report
- Focus on critical paths
-
Add tests
- Test uncovered branches
- Test error cases
- Test edge cases
-
Verify improvement
pnpm test -- --coverage
CI Integration
Tests run automatically in CI:
# .github/workflows/test.yml
- name: Run tests
run: pnpm test
- name: Check coverage
run: pnpm test -- --coverage
Test Best Practices
Good Test
describe('specific feature', () => {
it('should have expected behavior', () => {
// Arrange
const input = createTestData()
// Act
const result = processInput(input)
// Assert
expect(result).toBe(expected)
})
})
Test Naming
- Describe the behavior, not implementation
- Use "should" for expectations
- Be specific and clear
// Good
it('should install pnpm when version is specified')
// Less clear
it('installs pnpm')
Performance
Slow Tests
If tests are slow:
# Identify slow tests
pnpm test -- --verbose
# Run tests in parallel (default)
pnpm test -- --maxWorkers=4
Optimize Tests
- Mock external calls
- Use test fixtures
- Avoid unnecessary setup
- Clean up resources
Integration with Other Commands
Before Testing
Build the action:
quick:build
Fix code issues:
quick:fix
After Testing
Run quality checks:
quick:check
Implementation
This command executes:
#!/bin/bash
set -e
echo "=== Running Tests ==="
echo ""
# Run tests with coverage
pnpm test -- --coverage
echo ""
echo "Test run complete!"
echo ""
echo "To run specific tests:"
echo " pnpm test -- <test-file>"
echo ""
echo "To see coverage details:"
echo " open coverage/index.html"
Quick Reference
# Run all tests
pnpm test
# Run with coverage
pnpm test -- --coverage
# Run specific file
pnpm test -- inputs.test.ts
# Watch mode
pnpm test -- --watch
# Debug mode
pnpm test -- --verbose
# Update snapshots
pnpm test -- --updateSnapshot