Skip to content

Testing CLI (bin) Entries

The initial getting-started page involved us testing that our package imports and runs within other scripts (just like someone using our package as a library). Now though, let's assume that we've added a bin entry to our package.json so that people can use our tool via the cli.

In this case, we're counting on the package manager to fire up the binary we provided (under the hood this looks like a node-like call). Given that the package manager is making decisions for us though, we probably want to test the bin script that we're creating under those package manager constraints (and any module loading limitations of commonjs vs esm).

Let's go ahead and add a pretend cli command to our project (assuming you have a typescript project set up):

{
    "name": "mypkg",
    "bin": {
        "hello": "dist/bin/hello.js",
    }
    // Other fields and dependencies
}
{
    "module": "commonjs",
    "moduleResolution": "node",
    "target": "es2020",
    "outDir": "dist",
    "rootDir": "src"
    // Other fields
}
console.log("hello!")

To test the hello script that we built, let's modify our pkgtest.config.js from the initial getting-started:

pkgtest.config.js
module.exports = {
    entries: [
        {
            binTests: {},
            fileTests: {
                testMatch: "pkgtests/**/*.ts",
                runWith: ["node", "ts-node", "tsx"],
                transforms: {
                    typescript: {
                        version: '^5.0.0',
                        tsNode: {
                            version: '^10.9.2'
                        },
                        tsx: {
                            version: '^4.19.2',
                        },
                        nodeTypes: {
                            version: '^20.0.0',
                        } 
                    }
                },
            },
            packageManagers: [
                "yarn-v1",
                "yarn-berry",
                "npm", 
                "pnpm",
            ],
            moduleTypes: ["commonjs", "esm"],
            // No additional files needed
        },
    ],
    locks: false,
}
pkgtest.config.js
export default {
    entries: [
        {
            fileTests: {
                binTests: {},
                testMatch: "pkgtests/**/*.ts",
                runWith: ["node", "ts-node", "tsx"],
                transforms: {
                    typescript: {
                        version: '^5.0.0',
                        tsNode: {
                            version: '^10.9.2'
                        },
                        tsx: {
                            version: '^4.19.2',
                        },
                        nodeTypes: {
                            version: '^20.0.0',
                        } 
                    }
                },
            },
            packageManagers: [
                "yarn-v1",
                "yarn-berry",
                "npm", 
                "pnpm",
            ],
            moduleTypes: ["commonjs", "esm"],
            // No additional files needed
        },
    ],
    locks: false,
}

Let's go ahead and run pkgtest:

yarn tsc  # Make sure you've compiled your bin file
yarn pkgtest

You should now see some new test suites reported:


...Additional Tests Tests...

Test Suite for Module esm, Package Manager yarn-berry (yarn node linked), Package Bin Commands
Test package location: /tmp/pkgTest-XXXXXXhgjVy3
Test:  corepack yarn@latest hello --help Passed 682 ms
        corepack yarn@latest hello --help:
Passed: 1
Failed: 0
Skipped: 0
Not Run: 0
Total: 1

[runner] File Test Suites:  24 passed, 24 total
[runner] File Tests:        24 passed, 24 total
[runner] Bin Test Suites:  8 passed, 8 total
[runner] Bin Tests:        8 passed, 8 total
[runner] Setup Time:       11.094 s
[runner] File Test Time:   40.655 s
[runner] Bin Test Time:    10.442 s

Understanding the output


Test Suite for Module esm, Package Manager yarn-berry (yarn node linked), Package Bin Commands
Test package location: /tmp/pkgTest-XXXXXXhgjVy3
Test:  corepack yarn@latest hello --help Passed 682 ms
        corepack yarn@latest hello --help:
Passed: 1
Failed: 0
Skipped: 0
Not Run: 0
Total: 1

Bin Test Suite

This is the output for a Bin Test Suite. As you can see, a bin test suite is the run of all bin commands in a given project for esm + package manager configuration. They are denoted by the Package Bin Commands string.

Tip

Try adding another bin entry to your package.json and re-run ("hello2": "dist/bin/hello.js"). You should see 2 tests now in the suite.

Bin Test


Test:  corepack yarn@latest hello --help Passed 682 ms
        corepack yarn@latest hello --help:

You may have also noticed that, even though we provided no arguments to binTests, pkgtest went ahead and created a test for hello. The hello test is just it's cli call and it uses --help as a flag.

By default, pkgtest will scan all bin entries in your package.json and create a --help cli call. pkgtest will then consider an exit code 0 to be a success on these bin calls.

Specific Arguments

Given how simple our cli call is, --help doesn't do anything for us (it doesn't even thrown an unrecognized flag error). If we wanted to be a bit more correct about out test, we can override the arguments that pkgtest uses.

    binTest: {
        hello: [
            {
                args: "",
            },
        ],
    }

Now, pkgtest will only run one test for hello and will call just hello with no args.

Tip

Try adding a second entry with different args. When you re-run, you should see 2 hello tests.