Search code examples
javascriptnode.jsunit-testingtestingnode-test-runner

How to execute the Node.js test runner via JavaScript API with multiple reporters?


The Node.js test runner supports using multiple reporters by specifying the command-line options --test-reporter and --test-reporter-destination multiple times.

For example, when executing the following command, the test runner will print the test results to standard output in spec format and write a JUnit-style XML report into the file junit.xml:

node --test --test-reporter spec --test-reporter-destination stdout --test-reporter junit --test-reporter-destination ./report.xml

The Node.js test runner can also be executed via JavaScript API, by using the function run:

import { join } from "node:path";
import { run } from "node:test";
import { spec } from "node:test/reporters";

run({ files: [join(import.meta.dirname, "test", "my.test.js")] })
  .compose(spec)
  .pipe(process.stdout);

Now, I have a scenario where I'm executing the run function from another script, and I want to execute it with two reporters, similar to the command-line example above. How can this be achieved?


Solution

  • You can always pipe the TestsStream returned by run to different destinations. From the Node.js stream.pipe documentation:

    It is possible to attach multiple Writable streams to a single Readable stream.

    The following example reports results to both the spec reporter and a JUnit XML file.

    import { createWriteStream } from "node:fs";
    import { join } from "node:path";
    import { run } from "node:test";
    import { junit, spec } from "node:test/reporters";
    
    const stream = run({ files: [join(import.meta.dirname, "test", "my.test.js")] });
    
    stream.compose(junit).pipe(createWriteStream("unit.xml", "utf-8"));
    stream.pipe(spec()).pipe(process.stdout);