Introduction
This guide will help you integrate OtterWise with your Node.js project to track code coverage. OtterWise supports all major Node.js testing frameworks and works with both JavaScript and TypeScript projects.
Whether you're building APIs with Express, full-stack applications with Next.js, or enterprise applications with NestJS, this guide covers the setup for your specific use case.
Prerequisites
Before setting up OtterWise for your Node.js project, you'll need:
- A GitHub repository connected to OtterWise
- Node.js installed (version 18.x or higher recommended)
- A testing framework configured in your project
- Your OtterWise repository token (found in your repository settings after enabling it in OtterWise)
Supported Coverage Formats
OtterWise supports the following coverage formats for Node.js projects:
- LCOV - The most common format, supported by all major Node.js coverage tools
- Clover XML - Alternative XML format (less common for Node.js but supported)
We recommend using LCOV format as it's the standard for JavaScript/TypeScript projects.
Setup with Jest
Jest is the most popular testing framework for Node.js projects. It includes built-in code coverage support powered by Istanbul.
Installation
If you haven't already installed Jest, add it to your project:
npm install --save-dev jest
For TypeScript projects, you'll also need:
npm install --save-dev @types/jest ts-jest
Configuration
Create or update your jest.config.js
file to enable coverage collection:
module.exports = { collectCoverage: true, coverageDirectory: 'coverage', coverageReporters: ['lcov', 'text'], collectCoverageFrom: [ 'src/**/*.{js,jsx,ts,tsx}', '!src/**/*.d.ts', '!src/**/*.test.{js,jsx,ts,tsx}', ], };
Running Tests with Coverage
Add a coverage script to your package.json
:
{ "scripts": { "test": "jest", "test:coverage": "jest --coverage" } }
Run tests with coverage:
npm run test:coverage
This will generate a coverage report at coverage/lcov.info
.
Uploading to OtterWise
After generating the coverage report, upload it to OtterWise using the bash uploader:
# Using environment variable export OTTERWISE_TOKEN=your-repo-token bash <(curl -s https://raw.githubusercontent.com/getOtterWise/bash-uploader/main/uploader.sh) # Or pass token directly bash <(curl -s https://raw.githubusercontent.com/getOtterWise/bash-uploader/main/uploader.sh) --repo-token your-repo-token
Setup with Vitest
Vitest is a blazing-fast unit test framework powered by Vite. It's particularly popular for modern TypeScript projects and Vue/React applications.
Installation
npm install --save-dev vitest @vitest/coverage-v8
Vitest supports multiple coverage providers. We recommend @vitest/coverage-v8
(default) or @vitest/coverage-istanbul
.
Configuration
Add coverage configuration to your vite.config.ts
or vitest.config.ts
:
import { defineConfig } from 'vitest/config' export default defineConfig({ test: { coverage: { provider: 'v8', reporter: ['lcov', 'text'], include: ['src/**/*.{js,ts,jsx,tsx}'], exclude: ['src/**/*.test.{js,ts,jsx,tsx}', 'src/**/*.d.ts'], }, }, })
Running Tests with Coverage
Add scripts to your package.json
:
{ "scripts": { "test": "vitest", "test:coverage": "vitest --coverage" } }
Run tests with coverage:
npm run test:coverage
This will generate a coverage report at coverage/lcov.info
.
Setup with Mocha + NYC
Mocha is a flexible testing framework that requires a separate coverage tool. NYC (Istanbul CLI) is the most popular choice.
Installation
npm install --save-dev mocha nyc
Configuration
Create a .nycrc.json
file in your project root:
{ "all": true, "include": ["src/**/*.js", "src/**/*.ts"], "exclude": [ "src/**/*.test.js", "src/**/*.spec.js", "src/**/*.d.ts" ], "reporter": ["lcov", "text"], "report-dir": "coverage" }
Running Tests with Coverage
Add scripts to your package.json
:
{ "scripts": { "test": "mocha", "test:coverage": "nyc mocha" } }
Run tests with coverage:
npm run test:coverage
Setup with Node.js Native Test Runner + c8
Node.js 18+ includes a built-in test runner. For coverage, you can use c8, a native V8 coverage tool.
Installation
npm install --save-dev c8
Configuration
Create a .c8rc.json
file:
{ "all": true, "include": ["src/**/*.js", "src/**/*.mjs"], "exclude": ["src/**/*.test.js", "src/**/*.spec.js"], "reporter": ["lcov", "text"], "report-dir": "coverage" }
Running Tests with Coverage
Add scripts to your package.json
:
{ "scripts": { "test": "node --test", "test:coverage": "c8 node --test" } }
Framework-Specific Setup
Next.js
Next.js projects typically use Jest. Follow the Jest setup instructions above, but use this Jest configuration optimized for Next.js:
// jest.config.js const nextJest = require('next/jest') const createJestConfig = nextJest({ dir: './', }) const customJestConfig = { collectCoverage: true, coverageDirectory: 'coverage', coverageReporters: ['lcov', 'text'], collectCoverageFrom: [ 'app/**/*.{js,jsx,ts,tsx}', 'pages/**/*.{js,jsx,ts,tsx}', 'components/**/*.{js,jsx,ts,tsx}', 'lib/**/*.{js,jsx,ts,tsx}', '!**/*.d.ts', '!**/node_modules/**', '!**/.next/**', ], testEnvironment: 'jest-environment-jsdom', } module.exports = createJestConfig(customJestConfig)
NestJS
NestJS projects use Jest by default. The framework provides built-in testing utilities. Use this configuration:
// jest.config.js or package.json jest section { "moduleFileExtensions": ["js", "json", "ts"], "rootDir": "src", "testRegex": ".*\\.spec\\.ts$", "transform": { "^.+\\.(t|j)s$": "ts-jest" }, "collectCoverage": true, "coverageDirectory": "../coverage", "coverageReporters": ["lcov", "text"], "collectCoverageFrom": [ "**/*.(t|j)s", "!**/*.spec.ts", "!**/*.module.ts", "!**/main.ts" ], "testEnvironment": "node" }
Express.js
Express projects work with any testing framework. We recommend Mocha + NYC or Jest. No special configuration needed beyond the standard setup for your chosen framework.
CI Integration Examples
GitHub Actions
Here's a complete example for a Node.js project using GitHub Actions with the official OtterWise action:
name: Tests on: push: branches: [ main ] pull_request: branches: [ main ] jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 with: fetch-depth: 2 - name: Setup Node.js uses: actions/setup-node@v3 with: node-version: '20' cache: 'npm' - name: Install dependencies run: npm ci - name: Run tests with coverage run: npm run test:coverage - name: Upload Coverage to OtterWise uses: getOtterWise/github-action@v1 with: token: ${{ secrets.OTTERWISE_TOKEN }}
Important
Remember to add your OTTERWISE_TOKEN
to GitHub Secrets (Settings > Secrets and variables > Actions).
GitLab CI
test: image: node:20 stage: test script: - npm ci - npm run test:coverage - bash <(curl -s https://raw.githubusercontent.com/getOtterWise/bash-uploader/main/uploader.sh) --repo-token $OTTERWISE_TOKEN coverage: '/Lines\s*:\s*(\d+\.\d+)%/' artifacts: reports: coverage_report: coverage_format: cobertura path: coverage/cobertura-coverage.xml
CircleCI
version: 2.1 jobs: test: docker: - image: cimg/node:20.0 steps: - checkout - restore_cache: keys: - v1-dependencies-{{ checksum "package-lock.json" }} - run: name: Install Dependencies command: npm ci - save_cache: paths: - node_modules key: v1-dependencies-{{ checksum "package-lock.json" }} - run: name: Run Tests with Coverage command: npm run test:coverage - run: name: Upload Coverage to OtterWise command: bash <(curl -s https://raw.githubusercontent.com/getOtterWise/bash-uploader/main/uploader.sh) --repo-token $OTTERWISE_TOKEN workflows: version: 2 test: jobs: - test
Quick Reference: Coverage Commands
Framework | Command | Output Location |
---|---|---|
Jest | jest --coverage |
coverage/lcov.info |
Vitest | vitest --coverage |
coverage/lcov.info |
Mocha + NYC | nyc mocha |
coverage/lcov.info |
Node.js + c8 | c8 node --test |
coverage/lcov.info |
Next.js | jest --coverage |
coverage/lcov.info |
NestJS | npm run test:cov |
coverage/lcov.info |
Monorepo Support
If you're working with a monorepo (using tools like Turborepo, Nx, or Lerna), you can use the --flag
option
to track coverage separately for each package:
# Upload coverage for the API package bash <(curl -s https://raw.githubusercontent.com/getOtterWise/bash-uploader/main/uploader.sh) \ --repo-token $OTTERWISE_TOKEN \ --file ./packages/api/coverage/lcov.info \ --flag api # Upload coverage for the web package bash <(curl -s https://raw.githubusercontent.com/getOtterWise/bash-uploader/main/uploader.sh) \ --repo-token $OTTERWISE_TOKEN \ --file ./packages/web/coverage/lcov.info \ --flag web
Troubleshooting
Common Issues and Solutions
Issue | Solution |
---|---|
Coverage file not found |
|
Low coverage reported |
|
TypeScript files not covered |
|
Authentication errors |
|
Git diff issues in CI |
|
Debugging Coverage Generation
To verify your coverage is being generated correctly:
# Run coverage locally npm run test:coverage # Check if the file exists ls -la coverage/lcov.info # View the first few lines to verify format head -20 coverage/lcov.info
A valid LCOV file should look like this:
TN: SF:/path/to/your/src/file.ts FN:5,(anonymous_0) FNF:1 FNH:1 FNDA:1,(anonymous_0) DA:1,1 DA:2,1 ...
Additional Upload Options
The OtterWise bash uploader supports several options for advanced use cases. See the Bash Uploader documentation for complete details.
Common options for Node.js projects:
# Specify custom coverage file location bash <(curl -s https://raw.githubusercontent.com/getOtterWise/bash-uploader/main/uploader.sh) \ --repo-token $OTTERWISE_TOKEN \ --file ./custom/path/lcov.info # Add a flag for test suite identification bash <(curl -s https://raw.githubusercontent.com/getOtterWise/bash-uploader/main/uploader.sh) \ --repo-token $OTTERWISE_TOKEN \ --flag unit-tests # Quiet mode for cleaner CI logs bash <(curl -s https://raw.githubusercontent.com/getOtterWise/bash-uploader/main/uploader.sh) \ --repo-token $OTTERWISE_TOKEN \ --quiet
Next Steps
Once you have coverage data uploading successfully, you can:
- Configure Pull Request comments to see coverage changes in your PRs
- Set up status checks to enforce coverage thresholds
- Enable line annotations to highlight uncovered code in PRs
- Use badges to display your coverage status in your README
For additional help, check our example repository or contact OtterWise support.