Test Node CLI with Tape

Jida Asare
2 min readMar 21, 2021

Tape is a testing framework for JavaScript /Node js with a minimal core. Just as described here It is a tap-producing test harness for node and browsers. It requires no configuration to set up, does not require CLI to run test and the tests are just javascript hence can be simply run as a script with Nodejs.eg node my-script.test.js.
This tutorial does not cover introduction to testing using tape. However to familiarize yourself with such, kindly see the list of suggested resources below.

In this example, we will be testing a node CLI called Pizza. This example pizza was adopted from the pizza example in commander .
However ,this CLI is rewritten using Yargs, a Nodejs library for writing command-line tools.

PROJECT SETUP

To set up the project for testing, run the following commands in the terminal:

git clone https://github.com/jakazzy/pizzacd pizzanpm install 

The commands above will clone the pizza CLI repository and install the dependencies in the project.
The dependencies required in this project include:
i. yargs
The dev dependencies required in this project include:
i. tape
ii. tap-spec

RUN PIZZA CLI

Run the commands below in the terminal :

$ node ./bin/index -p -c mozzarella

The output will be

$ you ordered a pizza with:
$ — peppers
$ — gouda cheese

Alternatively running

$ node ./bin/index -p -C $ you ordered a pizza with:
$ — peppers

Testing the Pizza CLI

At the root of the project, create a folder called test. Within the test folder, create a file called option.test.js

mkdir testcd test && touch option.test.js

To test the first pizza command, we need to include the following code in the option.test.js file


const test = require(‘tape’)
const { createCLIWrapper } = require(‘./test-utils’)
// tape, child_process, and assert on stderr/stdout/exit code test(`pizza orders`, (t)=>{
t.plan(2)
t.test(`’-p -C’ should return You ordered a pizza with:” \n- peppers`,
t => {
const wrapper = createCLIWrapper()
const result = wrapper.run([‘-p’, ‘-C’])
t.ok(result.stdout.includes(`You ordered a pizza with:”\n- peppers`))
t.end()})
})

In the test folder create a file test-utils.js

touch test-utils.js

Include the following in the test-utils.js

const { spawnSync } = require(‘child_process’)

const _runCli = ( command ) => {
return spawnSync(‘node’, [‘../pizza/bin/index’,…command], { encoding: ‘utf-8’ }) }
function createCLIWrapper () {
return {
run: _runCli
}
}
module.exports = {
createCLIWrapper
}

The above code creates an instance of a child process and launches a command within the child process with its arguments and inputs inorder to run the pizza CLI.

We then the option.test.js file, We check the output for running the the command


node ./bin/index -p -C

and verify if its output is includes

`You ordered a pizza with:"\n- peppers`

The test passes if the assertion is true and fails if the assertion is false.

As exercise, try writing test for running the command?

node ./bin/index -p -c mozarrella

Do check for the repository https://github.com/jakazzy/pizza For the complete solution.

Suggested Resources for Tape
1. Learn Tape — https://github.com/dwyl/learn-tape
2. Tape — https://github.com/substack/tape
3. Tape — https://catonmat.net/writing-javascript-tests-with-tape

--

--