A small utility to create parameterized tests for
node:testusing "macros."
Requires Node.js ^22.22.2, ^24.15.0, or >=26.0.0
npm install node-test-macro -Dnode-test-macro ships both CJS and ESM builds.
node-test-macro exports createMacro(). When invoked, createMacro() returns a factory function. This factory function returns a TestOptions object which is passed directly to node:test's test()/it().
Each macro can accept a user-defined "options" bag which is passed into the MacroTestFn. This function is essentially the same as the usual TestFn, except it additionally receives the user-defined options as the second parameter.
In this form, the macro is implemented as a function which receives the test context and user-defined options object.
import{it,typeTestContext}from'node:test';import{createMacro}from'node-test-macro';conststringCompare=createMacro((t: TestContext,{ actual, expected }: {actual: string;expected: string},)=>{t.assert.strictEqual(actual,expected);},);// the second parameter to stringCompare is a TestOptions objectit('string comparison',stringCompare({actual: 'foo',expected: 'foo'},{plan: 1}),);In this form, createMacro() accepts a MacroConfig object containing at minimum an exec function which is the same as the first parameter in the "basic" example.
A title function (or string) can be provided to derive the test name from the options object.
Additionally, a testOptions object can be provided to set the default set of test options, which can optionally be overridden when the macro is invoked.
import{it,typeTestContext}from'node:test';import{createMacro}from'node-test-macro';conststringCompare=createMacro({exec: (t: TestContext,{ actual, expected }: {actual: string;expected: string},)=>{t.assert.strictEqual(actual,expected);},title: ({ actual, expected })=>`${actual} === ${expected}`,testOptions: {timeout: 1_000},});it(stringCompare({actual: 'foo',expected: 'foo'},{plan: 1}));If for some as-yet-unknown reason you don't want to accept user-defined options, you can use
createMacro<void>().
Copyright © 2026 Christopher Hiller. Licensed BlueOak-1.0.0