@zohodesk/unit-testing-framework
v0.0.31-experimental
Published
A modular Jest-based unit testing framework
Maintainers
Keywords
Readme
@zohodesk/unit-testing-framework
A modular, Jest-based unit testing framework designed to plug into existing CLI pipelines. Runs Jest programmatically via @jest/core (no shell execution), ships with sensible defaults, HTML report generation via jest-html-reporter, and automatic Jest globals injection.
Folder Structure
unit-testing-framework/
├── package.json # Package config (publishes build/ only)
├── babel.config.json # Babel config – ESM → CJS for Node 18
├── index.js # Public API entry point
├── src/
│ ├── runner/
│ │ ├── jest-runner.js # createJestRunner() – main orchestrator
│ │ └── runner-base.js # buildArgv() & executeJest() via @jest/core
│ ├── config/
│ │ └── default-config.js # getDefaultConfig() – framework defaults
│ ├── environment/
│ │ └── globals-inject.js # Injects jest into globalThis (setup file)
│ └── utils/
│ └── logger.js # Colored console logger utility
├── build/ # Transpiled output (published to npm)
├── examples/
│ └── consumer-cli.js # Example CLI integration
└── README.mdInstallation
npm install @zohodesk/unit-testing-frameworkAll Jest dependencies (@jest/core, jest-environment-jsdom, babel-jest) are bundled — consumers don't need to install Jest separately.
Quick Start
import { createJestRunner } from '@zohodesk/unit-testing-framework';
// Run all tests with framework defaults
const results = await createJestRunner();
process.exitCode = results.numFailedTests > 0 ? 1 : 0;Run a specific test file by pattern:
const results = await createJestRunner({
testPathPattern: 'login.test.js',
});Enable watch mode:
await createJestRunner({ watch: true });API
createJestRunner(options?)
| Option | Type | Default | Description |
|---|---|---|---|
| projectRoot | string | process.cwd() | Consumer project root directory |
| testPathPattern | string | — | Filter tests by file path pattern |
| watch | boolean | false | Enable Jest watch mode |
Returns: Promise<AggregatedResult> — Jest's aggregated results object.
Default Configuration
The framework provides a complete Jest config via getDefaultConfig(projectRoot):
| Setting | Value |
|---|---|
| testMatch | ['**/__tests__/**/*.test.js'] |
| testEnvironment | jsdom |
| transform | Babel with @babel/preset-env |
| testTimeout | 20 000 ms |
| automock | false |
| clearMocks | true |
| passWithNoTests | true |
| testPathIgnorePatterns | ['/build/'] |
Reporters
Two reporters are enabled by default:
default— Jest's built-in console reporter, prints pass/fail/skip summary to the terminal.jest-html-reporter— generates an HTML test report using thejest-html-reporterpackage.
HTML Reporter Configuration
| Option | Value | Description |
|---|---|---|
| outputPath | <rootDir>/test-slices/unit-test/unit_reports/report.html | Path for the generated report |
| pageTitle | Unit Test Report | Page title |
| includeFailureMsg | true | Show failure messages in the report |
| includeSuiteFailure | true | Show suite-level failures |
| theme | darkTheme | Dark-themed report |
Globals Injection
The framework's setupFiles automatically injects the jest object into globalThis, so test files can call jest.fn(), jest.mock(), etc. without explicit imports.
Example: CLI Integration
See examples/consumer-cli.js for a complete example:
import { createJestRunner } from '@zohodesk/unit-testing-framework';
const command = process.argv[2];
if (command === 'unit-test') {
const testFile = process.argv[3];
const results = await createJestRunner({
testPathPattern: testFile,
});
process.exitCode = results.numFailedTests > 0 ? 1 : 0;
} else if (command === 'unit-test:watch') {
await createJestRunner({ watch: true });
}Build
Source is written in ESM and transpiled to CommonJS via Babel.
npm run build # Transpile src/ → build/
npm run clean # Delete build/ and rebuildConsumer Config File
Place one of these in your project root (auto-discovered in order):
jest.unit.config.jsjest.unit.config.mjsjest.unit.config.json
// jest.unit.config.js
export default {
roots: ['<rootDir>/tests/unit'],
maxWorkers: 4,
collectCoverage: true,
reporters: ['default', 'framework-default'],
testTimeout: 60_000,
};Built-in Reporter Alias
Use 'framework-default' in the reporters array to include the bundled reporter.
Consumer CLI Integration
// In your existing CLI file
import createJestRunner from 'unit-testing-framework';
switch (option) {
case 'unit-test': {
const results = await createJestRunner();
process.exitCode = results.numFailedTests > 0 ? 1 : 0;
break;
}
case 'unit-test:coverage': {
const results = await createJestRunner({ coverage: true });
process.exitCode = results.numFailedTests > 0 ? 1 : 0;
break;
}
case 'unit-test:watch':
await createJestRunner({ watch: true });
break;
}Consumer Project Structure Example
my-app/
├── package.json # depends on unit-testing-framework
├── jest.unit.config.js # optional overrides
├── cli.js # existing CLI with switch/case
├── src/
│ └── utils/
│ └── math.js
└── tests/
└── unit/
└── math.test.jsPublishing
# 1. Login to npm
npm login
# 2. Verify package contents
npm pack --dry-run
# 3. Publish
npm publish
# For scoped packages:
npm publish --access publicVersioning
Follow semver:
npm version patch # 1.0.0 -> 1.0.1 (bug fixes)
npm version minor # 1.0.0 -> 1.1.0 (new features, backward-compatible)
npm version major # 1.0.0 -> 2.0.0 (breaking changes)
npm publishConsumer pins via package.json:
{
"dependencies": {
"unit-testing-framework": "^1.0.0"
}
}^1.0.0 allows auto-upgrade for minor/patch. Use exact pinning (1.0.0) for strict control.
License
MIT
