Skip to main content

Unit Tests Workflow (unit-tests.yml)

The Unit Tests Workflow provides comprehensive testing capabilities for all DashClicks services, supporting both Node.js and Deno-based applications. It features intelligent change detection to run tests only for modified services, extensive caching for performance, and detailed coverage reporting.

๐Ÿงช Overviewโ€‹

  • File: .github/workflows/unit-tests.yml
  • Purpose: Execute unit tests for Node.js and Deno services
  • Triggers: Pull requests and manual dispatch
  • Features: Smart change detection, parallel execution, coverage reporting
  • Platforms: Ubuntu 22.04 with Node.js 18 and Deno 2.1.7

๐Ÿ”„ Trigger Eventsโ€‹

on:
workflow_dispatch: # Manual execution
pull_request: # All pull requests to any branch
branches:
- '**'

๐Ÿ” Intelligent Change Detectionโ€‹

The workflow analyzes changed files to determine which test suites to run:

Service Categoriesโ€‹

# Node.js services (11 services)
NODE_SERVICES="conversation-socket dashboard-gateway external functions
general-socket internal misc notifications queue-manager
router tests"

# Deno services (1 service)
DENO_SERVICES="ai-service"

Change Detection Logicโ€‹

# Get changed files based on trigger type
if [ "${{ github.event_name }}" == "pull_request" ]; then
git fetch origin ${{ github.base_ref }}
CHANGED_FILES=$(git diff --name-only origin/${{ github.base_ref }}..HEAD)
else
CHANGED_FILES=$(git diff --name-only HEAD^..HEAD)
fi

# Determine which test suites to run
NODE_SERVICES_CHANGED="false"
for service in $NODE_SERVICES; do
if echo "$CHANGED_FILES" | grep -q "^$service/"; then
NODE_SERVICES_CHANGED="true"
break
fi
done

DENO_SERVICES_CHANGED="false"
if echo "$CHANGED_FILES" | grep -q "^ai-service/"; then
DENO_SERVICES_CHANGED="true"
fi

Test Execution Strategyโ€‹

ScenarioNode.js TestsDeno TestsResult
No changesSkipSkipAll tests skipped
Only Node.js changesRunSkipNode.js tests only
Only Deno changesSkipRunDeno tests only
Both changedRunRunFull test suite

๐Ÿ—๏ธ Node.js Test Setupโ€‹

Environment Configurationโ€‹

# Package management
uses: pnpm/action-setup@v2
with:
version: 9.x

# Node.js setup
uses: actions/setup-node@v4
with:
node-version: 18
cache: 'pnpm'

MongoDB Test Databaseโ€‹

# MongoDB Memory Server configuration
MONGOMS_VERSION: '6.0.9'
MONGOMS_DOWNLOAD_DIR: '/tmp/mongodb-binaries'
NODE_ENV: 'test'
MONGODB_DEBUG: '1'

Dependency Cachingโ€‹

# Comprehensive Node.js caching
path: |
~/.pnpm
node_modules
*/*/node_modules
tests/node_modules
internal/node_modules
external/node_modules
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json', '**/package.json') }}

Shared Files Distributionโ€‹

# Copy shared models and utilities
pnpm run copySharedFiles

# Install all dependencies
pnpm install --no-frozen-lockfile

๐Ÿงช Node.js Test Executionโ€‹

Test Commandโ€‹

pnpm test -- --coverage --testPathPattern="($NODE_PATTERN)"

Coverage Configurationโ€‹

The workflow generates comprehensive coverage reports:

  • Format: Jest coverage with multiple formats (JSON, LCOV, HTML)
  • Thresholds: Configurable minimum coverage requirements
  • Output: Coverage reports stored as artifacts

Test Pattern Filteringโ€‹

Tests run only for changed services using pattern matching:

# Example: If internal/ and external/ changed
--testPathPattern="(internal|external)"

๐Ÿฆ• Deno Test Setupโ€‹

Environment Configurationโ€‹

# Deno setup
uses: denoland/setup-deno@v2
with:
deno-version: 2.1.7

Test Executionโ€‹

cd ai-service
NO_COLOR=true NODE_ENV=test deno test \
--coverage=tests/coverage \
--allow-net \
--allow-env \
--allow-read

Coverage Generationโ€‹

# Generate coverage report
NO_COLOR=true NODE_ENV=test deno coverage tests/coverage

๐Ÿ“Š Test Results & Reportingโ€‹

Exit Code Handlingโ€‹

# Capture test results with proper exit codes
pnpm test 2>&1 | tee node-coverage-log.txt
TEST_EXIT_CODE=${PIPESTATUS[0]}
echo "exit_code=$TEST_EXIT_CODE" >> "$GITHUB_OUTPUT"

Error Captureโ€‹

# Capture specific error messages for Deno
ERROR_MSG=$(grep -A 5 "error:" ../deno-coverage-log.txt || true)
if [ -n "$ERROR_MSG" ]; then
echo "DENO_TEST_ERROR<<EOF" >> "$GITHUB_ENV"
echo "$ERROR_MSG" >> "$GITHUB_ENV"
echo "EOF" >> "$GITHUB_ENV"
fi

Failure Reportingโ€‹

The workflow fails if any test suite fails:

# Check for test failures
FAIL=false

if [ "${{ steps.node-tests.outputs.exit_code }}" != "0" ]; then
FAIL=true
echo "โŒ Node.js tests failed"
fi

if [ "${{ steps.deno-tests.outputs.exit_code }}" != "0" ]; then
FAIL=true
echo "โŒ Deno tests failed"
fi

if [ "$FAIL" = true ]; then
exit 1
fi

๐Ÿ“ฆ Artifacts & Coverageโ€‹

Upload Strategyโ€‹

# Upload comprehensive test artifacts
- name: ๐Ÿ“ฆ Upload test results
uses: actions/upload-artifact@v4
with:
name: test-results
path: |
coverage/
ai-service/coverage/
test-results/
node-coverage-log.txt
deno-coverage-log.txt
retention-days: 14

Coverage Analysisโ€‹

The workflow extracts coverage information:

# Node.js coverage extraction
coverageSummaryMatch = /File.*?(\d+\.\d+)\s*%.*?Branch.*?(\d+\.\d+)\s*%/s.exec(fullNodeCoverage);

# Deno coverage extraction
coverageSummaryMatch = /(\d+\.\d+)%.*?coverage/s.exec(fullDenoCoverage);

๐Ÿ’ฌ Pull Request Integrationโ€‹

Automated PR Commentsโ€‹

The workflow posts detailed test results to pull requests:

// Comment structure
const comment = `## ๐Ÿงช Unit Test Results

### ${statusEmoji} Status: ${statusMessage}

### ๐Ÿ“Š Run Information
- **Run ID**: [${context.runId}](${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId})
- **Triggered by**: ${context.actor}

### ๐Ÿ” Changed Files
${changedFilesList}

### ๐Ÿ“‹ Test Execution Summary
${testSummary}

### ๐ŸŸข Node.js Test Results Summary
${nodeCoverage}

### ๐Ÿฆ• Deno Test Results Summary
${denoCoverage}
`;

Comment Featuresโ€‹

  • Collapsible sections for detailed logs
  • Coverage summaries with key metrics
  • Error highlighting for failed tests
  • File change tracking with limits for readability
  • Direct links to workflow runs

๐Ÿ”ง Caching Configurationโ€‹

Cache Typesโ€‹

Cache TypePathKey
Node modules~/.pnpmPackage files hash
MongoDB binaries/tmp/mongodb-binariesMongoDB version
Chrome browserSystem defaultRunner OS

๐Ÿ› ๏ธ Environment Variablesโ€‹

MongoDB Configurationโ€‹

MONGOMS_VERSION: '6.0.9'
MONGOMS_DOWNLOAD_DIR: '/tmp/mongodb-binaries'
MONGODB_VERSION: '6.0.9'
MONGODB_TEST_URI: 'mongodb://localhost:27017/dashclicks_test'
MONGODB_DEBUG: '1'

Test Environmentโ€‹

NODE_ENV: 'test'
NO_COLOR: 'true' # Disable color output for Deno
SKIP_TESTS: 'false' # Control test execution
SKIP_NODE_TESTS: 'false'
SKIP_DENO_TESTS: 'false'

๐Ÿ” Debug Configurationโ€‹

Logging Variablesโ€‹

MONGODB_DEBUG: '1'
NODE_ENV: 'test'
NO_COLOR: 'true'

๐Ÿ“‹ Test Configurationโ€‹

Coverage Requirementsโ€‹

Minimum coverage thresholds enforced:

  • Branch coverage: 40% minimum
  • Function coverage: 50% minimum
  • Line coverage: 50% minimum
  • Statement coverage: 50% minimum

Environment Dependenciesโ€‹

  • Node.js 18: Runtime for Node.js services
  • Deno 2.1.7: Runtime for AI service
  • pnpm 9.x: Package manager
  • MongoDB 6.0.9: Test database via Memory Server
  • Chrome browser: For Puppeteer-based tests

๐Ÿ’ฌ

Documentation Assistant

Ask me anything about the docs

Hi! I'm your documentation assistant. Ask me anything about the docs!

I can help you with:
- Code examples
- Configuration details
- Troubleshooting
- Best practices

Try asking: How do I configure the API?
09:31 AM