From a57621bc7f50f3a9fff1f186bc7d1a733e9a43ae Mon Sep 17 00:00:00 2001 From: Maor Rozenfeld <49363375+maor-rozenfeld@users.noreply.github.com> Date: Wed, 7 Jan 2026 20:27:21 +0100 Subject: [PATCH] Add timing for tests --- .github/workflows/ci.yml | 11 +++- CONTRIBUTING.md | 2 +- TESTING.md | 115 +++++++++++++++++++++++++++++++++++++++ jest.preset.js | 20 +++++++ package.json | 2 + 5 files changed, 148 insertions(+), 2 deletions(-) create mode 100644 TESTING.md diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7fcb0b77bd..cc8359157b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -148,9 +148,18 @@ jobs: timeout_minutes: 10 max_attempts: 3 retry_on: error - command: npx nx run-many --target test --projects "${{ matrix.test-suits.include }}" --exclude "${{ matrix.test-suits.exclude }}" --quiet + command: npx nx run-many --target test --projects "${{ matrix.test-suits.include }}" --exclude "${{ matrix.test-suits.exclude }}" -- --verbose env: NX_REJECT_UNKNOWN_LOCAL_CACHE: 0 + CI: true + JEST_VERBOSE: true + - name: Upload test results + if: always() + uses: actions/upload-artifact@v4 + with: + name: test-results-${{ matrix.test-suits.key || matrix.test-suits.name }} + path: test-results/ + retention-days: 7 - name: Truncate NX cache run: ./tools/truncate-nx-cache.sh build: diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 7ae65f6158..fe919e9dbe 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -68,7 +68,7 @@ To contribute code changes: * Follow existing code style and patterns * Write clear, self-documenting code with descriptive variable and function names * Add comments for complex or non-obvious logic -5. **Test your changes**. Add or update tests to ensure your code works as expected and doesn't break existing functionality. +5. **Test your changes**. Add or update tests to ensure your code works as expected and doesn't break existing functionality. See [TESTING.md](./TESTING.md) for details on running tests with timing information. 6. **Commit changes** with clear, concise commit messages. 7. **Push to your fork**. 8. **Open a Pull Request** from your fork to this repository. diff --git a/TESTING.md b/TESTING.md new file mode 100644 index 0000000000..83973017e7 --- /dev/null +++ b/TESTING.md @@ -0,0 +1,115 @@ +# Testing Guide + +This document describes how to run tests with timing information in the OpenOps repository. + +## Running Tests with Timing + +### Local Development + +#### Option 1: Using npm scripts (Recommended) + +```bash +# Run all tests with timing information +npm run test:timing + +# Run all tests with verbose output +npm run test:verbose + +# Run tests for a specific project with timing +npx nx test -- --verbose +``` + +#### Option 2: Using nx directly + +```bash +# Run tests with timing for a specific project +JEST_VERBOSE=true npx nx test -- --verbose + +# Run tests with timing for all projects +JEST_VERBOSE=true npx nx run-many --target=test -- --verbose + +# Run tests with timing for affected projects only +JEST_VERBOSE=true npx nx affected --target=test -- --verbose +``` + +### Examples + +```bash +# Run engine tests with timing +npx nx test engine -- --verbose + +# Run server-api tests with timing +npx nx test server-api -- --verbose + +# Run all UI tests with timing +npx nx run-many --target=test --projects="ui-*" -- --verbose +``` + +## Understanding Test Output + +When running tests with `--verbose` flag, you'll see: + +- **Individual test execution time**: Each test shows its duration in milliseconds +- **Test suite total time**: Total time taken for each test suite +- **Overall execution time**: Total time for all test suites + +Example output: +``` + PASS shared packages/shared/test/common/utils/extract-string-property.test.ts + extractStringProperty + ✓ should extract string property (5 ms) + ✓ should handle missing property (1 ms) + ✓ should handle nested properties (2 ms) + +Test Suites: 1 passed, 1 total +Tests: 3 passed, 3 total +Snapshots: 0 total +Time: 1.284 s +``` + +## CI/CD Integration + +In GitHub Actions (CI environment), tests automatically: + +1. Run with `--verbose` flag for detailed timing information +2. Generate JUnit XML reports in `test-results/` directory +3. Upload test results as artifacts with 7-day retention +4. Display timing for each test and test suite in the CI logs + +### Viewing CI Test Results + +1. Navigate to the GitHub Actions workflow run +2. Check the "Test" job logs to see timing information +3. Download test result artifacts for detailed analysis + +## Test Result Artifacts + +JUnit XML reports are generated in CI and include: + +- Test execution times +- Test suite execution times +- Pass/fail status +- File paths and test names + +These artifacts can be: +- Downloaded from GitHub Actions artifacts +- Integrated with test reporting tools +- Used for performance analysis and tracking + +## Configuration + +Test timing is configured in: + +- **jest.preset.js**: Global Jest configuration with reporters + - Uses `jest-junit` reporter in CI mode + - Enables verbose mode via `JEST_VERBOSE` environment variable +- **.github/workflows/ci.yml**: CI workflow configuration + - Sets `CI=true` and `JEST_VERBOSE=true` environment variables + - Uploads test results as artifacts + +## Performance Tips + +- Individual tests taking >100ms may indicate performance issues +- Test suites taking >5s should be reviewed for optimization +- Use `--verbose` selectively in local development to avoid output clutter +- In CI, verbose output helps diagnose slow or flaky tests diff --git a/jest.preset.js b/jest.preset.js index 0116eb24eb..cebc82b929 100644 --- a/jest.preset.js +++ b/jest.preset.js @@ -14,4 +14,24 @@ module.exports = { snapshotFormat: { escapeString: true, printBasicPrototype: true }, transformIgnorePatterns: ['node_modules/(?!(lodash-es)/)'], setupFilesAfterEnv: [__dirname + '/jest.setup.js'], + reporters: [ + 'default', + ...(process.env.CI === 'true' + ? [ + [ + 'jest-junit', + { + outputDirectory: './test-results', + outputName: 'junit.xml', + classNameTemplate: '{filepath}', + titleTemplate: '{title}', + ancestorSeparator: ' › ', + usePathForSuiteName: true, + addFileAttribute: 'true', + }, + ], + ] + : []), + ], + verbose: process.env.JEST_VERBOSE === 'true', }; diff --git a/package.json b/package.json index 221371225d..2d6dcea23a 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,8 @@ "pull-i18n": "crowdin pull --config crowdin.yml", "push-i18n": "crowdin upload sources", "i18n:extract": "i18next --config packages/react-ui/i18next-parser.config.js && jq 'to_entries | map({(.key): .key}) | add' packages/react-ui/public/locales/en/translation.json > packages/react-ui/public/locales/en/translation.tmp.json && mv packages/react-ui/public/locales/en/translation.tmp.json packages/react-ui/public/locales/en/translation.json", + "test:verbose": "cross-env JEST_VERBOSE=true nx run-many --target=test -- --verbose", + "test:timing": "cross-env JEST_VERBOSE=true nx run-many --target=test -- --verbose", "storybook": "nx run ui-components:storybook", "build-storybook": "nx run ui-components:build-storybook --", "chromatic": "npx chromatic --",