TypeScript xUnit XML Reporter
The `typescript-xunit-xml` package provides a command-line interface and a programmatic API for converting the diagnostic output of the TypeScript compiler (`tsc`) into an xUnit-style XML format. This conversion is highly beneficial for integrating TypeScript build processes with continuous integration (CI) systems like Jenkins, GitLab CI, or Azure DevOps, allowing them to interpret compilation errors and warnings as test failures. The package is currently at version 1.2.0, with its last publish occurring approximately three years ago, suggesting a maintenance rather than active development cadence. Its primary differentiator lies in its focused design specifically for `tsc` output, offering a streamlined solution for reporting TypeScript-specific issues without requiring broader testing frameworks. While it functions effectively as a CLI tool via pipe operations, it also exposes `parse` and `format` functions for direct programmatic use within Node.js applications, enabling more custom integration scenarios.
Common errors
-
'typescript-xunit-xml' is not recognized as an internal or external command, operable program or batch file.
cause The `typescript-xunit-xml` CLI tool is not found in the system's PATH or within `node_modules/.bin`.fixInstall the package globally (`npm install -g typescript-xunit-xml`), or use `npx typescript-xunit-xml`, or ensure `node_modules/.bin` is in your PATH in shell scripts. -
tsc: The term 'tsc' is not recognized as the name of a cmdlet, function, script file, or operable program.
cause The TypeScript compiler (`tsc`) is not installed globally or is not accessible in the execution environment's PATH.fixInstall TypeScript globally (`npm install -g typescript`) or ensure `tsc` is available in your project's `node_modules/.bin` (e.g., by adding `"scripts": { "test": "tsc && ..." }` to `package.json` and running `npm test`). -
Error: Invalid TS diagnostics output. Expected format...
cause The input provided to `typescript-xunit-xml` (via pipe or programmatic `parse` function) is not in the expected format of standard TypeScript compiler diagnostics, likely due to a `--pretty` flag or other output modifications.fixEnsure `tsc` is run without the `--pretty` flag and that no other tools are altering its `stdout` or `stderr` before it reaches `typescript-xunit-xml`.
Warnings
- breaking The package relies on parsing the standard output format of the TypeScript compiler (tsc). Any future breaking changes to tsc's diagnostic output format could lead to incorrect parsing or runtime errors within `typescript-xunit-xml`.
- gotcha Currently, `typescript-xunit-xml` does not support parsing `--pretty` output from the TypeScript compiler. Using `--pretty` will result in malformed or incomplete XML reports.
- gotcha When running `tsc` in environments that buffer stdout/stderr or modify output (e.g., some CI runners, IDE integrations), the raw output might be altered before reaching `typescript-xunit-xml`, leading to parsing failures.
- gotcha TypeScript compiler warnings are typically reported by `typescript-xunit-xml` as 'skipped' tests in the xUnit report, while errors are reported as 'failures'. This distinction is important for CI systems that differentiate between these states.
Install
-
npm install typescript-xunit-xml -
yarn add typescript-xunit-xml -
pnpm add typescript-xunit-xml
Imports
- parse
import parse from 'typescript-xunit-xml';
import { parse } from 'typescript-xunit-xml'; - format
import format from 'typescript-xunit-xml';
import { format } from 'typescript-xunit-xml'; - { parse, format } (CommonJS)
const converter = require('typescript-xunit-xml'); // Then access converter.parse, converter.formatconst { parse, format } = require('typescript-xunit-xml');
Quickstart
import { readFileSync, writeFileSync } from 'fs';
import { spawnSync } from 'child_process';
import { parse, format } from 'typescript-xunit-xml'; // Programmatic API
const tsConfigFile = 'tsconfig.json';
const tsCodeFile = 'src/index.ts';
// Ensure src directory exists and create dummy files for demonstration
if (!require('fs').existsSync('src')) require('fs').mkdirSync('src');
writeFileSync(tsCodeFile, `
function greet(name: string): string {
return \`Hello, \${name}!\`;
}
const x: number = 'hello'; // Intentionally cause a type error for the demo
console.log(greet("World"));
`);
writeFileSync(tsConfigFile, `
{
"compilerOptions": {
"target": "es2016", "module": "commonjs", "strict": true,
"esModuleInterop": true, "skipLibCheck": true,
"forceConsistentCasingInFileNames": true, "noEmit": true
},
"include": ["src/**/*.ts"]
}
`);
console.log("Running tsc and piping output to typescript-xunit-xml...");
// Simulate the CLI usage: tsc --project . --noEmit | typescript-xunit-xml
// The --noEmit flag is crucial for tsc to output diagnostics to stdout/stderr instead of compiling files.
const tscProcess = spawnSync('tsc', ['--project', '.', '--noEmit'], { encoding: 'utf8' });
if (tscProcess.status !== 0) {
console.warn("TypeScript compilation errors detected (expected for this demo).");
} else {
console.log("No TypeScript errors. Outputting empty xUnit XML.");
}
// tsc often sends errors to stderr, so check both
const tscOutput = (tscProcess.stderr || tscProcess.stdout).toString();
// Use the programmatic API to process the output
const parsedMessages = parse(tscOutput);
const xunitXml = format(parsedMessages);
writeFileSync('junit.xml', xunitXml);
console.log("Generated junit.xml with xUnit report (check 'junit.xml' for content):");
// console.log(xunitXml); // Uncomment to see the XML directly in console
// Clean up dummy files
try {
require('fs').unlinkSync(tsCodeFile);
require('fs').unlinkSync(tsConfigFile);
require('fs').rmdirSync('src');
console.log("Cleaned up dummy files.");
} catch (e) {
console.error("Cleanup failed:", e.message);
}