SkillAgentSearch skills...

Tappedout

A simple "back to basics" JavaScript test runner for producing TAP-formatted results. Built using ES Modules.

Install / Use

/learn @coreybutler/Tappedout
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

tappedout

A simple "back to basics" JavaScript test runner for producing TAP-formatted results. It is runtime agnostic and built using ES Modules.

It is built using ES module syntax, drawing inspiration from the tape library. It shares several similarities, but should not be considered "the same". The API has several different methods. Furthermore, tappedout is runtime-agnostic. It will work in browsers, Node, Deno, and any other ECMAScript-compliant (ES5+) runtime.

This is for library authors...

There are many beautiful test runners. They often come at the price of requiring many dependencies, which may be fine for a single complex project. Library authors typically maintain multiple smaller repos containing smaller bits of code. The black hole of node_modules was way too heavy when multiplied across multiple projects. Since tappedout is written using ECMAScript standard modules, there is no need for pre-processing/transpiling just to run tests.

The name came from frustration. My patience was tapped out with one too many rollup/browserify processes.

Getting tappedout

Node.js

This library only supports versions of Node with ES Module support. This is available in Node 12 & 13 using the --experimental-modules flag. It is a native feature in Node 14+ (no flag needed). All versions need to specify "type": "module" in the package.json file.

Obtaining the module:

npm i tappedout --save-dev

Implementing it in Node:

import test from 'tappedout'

Browser, Deno

Version

import test from 'https://cdn.pika.dev/tappedout^1.0.0' // <-- Update the version

Usage

Here's a basic example:

import test from 'tappedout'

test('My Test Suite', t => {
  t.ok(true, 'I am OK.')
  t.ok(false, 'I am still OK.') // Expect a failure here!
})

Output:

TAP version 13
# My Test Suite
ok 1 - I am OK.
not ok 2 - I am still OK.
1..2

Alternative output formats:

TAP (Test Anything Protocol) is a language-agnostic format for documenting test results. There is a companion formatting tool, tapfmt, providing a language/runtime-agnostic standalone formatter. There are also many different runtime-specific formatters available if you search npm/github. It's relatively easy to create your own using tap-parser or a similar library.

TAP producers generally output to stdout/stderr (console). However, there are some circumstances where an alternative output mechanism is desired. The tappedout library supports overriding the default output mechanism. For example, to use a custom handler, set the logger as:

import test from 'tappedout'

test.logger = function () {
  // Prefix 'TAP:' to every line
  console.log(`TAP:`, ...arguments)
}

test('title', t => { ... }})

The most common reason for overriding the output mechanism is for writing results to a file.

Pretty Output:

This library only outputs raw TAP results.

Combine it with a post-processor for "pretty" output.

<details> <summary>TAP Post-Processors/Formatters</summary> <ol> <li><a href="https://github.com/scottcorgan/tap-spec">tap-spec</a></li> <li><a href="https://github.com/scottcorgan/tap-dot">tap-dot</a></li> <li><a href="https://github.com/substack/faucet">faucet</a></li> <li><a href="https://github.com/juliangruber/tap-bail">tap-bail</a></li> <li><a href="https://github.com/kirbysayshi/tap-browser-color">tap-browser-color</a></li> <li><a href="https://github.com/gummesson/tap-json">tap-json</a></li> <li><a href="https://github.com/derhuerst/tap-min">tap-min</a></li> <li><a href="https://github.com/calvinmetcalf/tap-nyan">tap-nyan</a></li> <li><a href="https://www.npmjs.org/package/tap-pessimist">tap-pessimist</a></li> <li><a href="https://github.com/toolness/tap-prettify">tap-prettify</a></li> <li><a href="https://github.com/shuhei/colortape">colortape</a></li> <li><a href="https://github.com/aghassemi/tap-xunit">tap-xunit</a></li> <li><a href="https://github.com/namuol/tap-difflet">tap-difflet</a></li> <li><a href="https://github.com/gritzko/tape-dom">tape-dom</a></li> <li><a href="https://github.com/axross/tap-diff">tap-diff</a></li> <li><a href="https://github.com/axross/tap-notify">tap-notify</a></li> <li><a href="https://github.com/zoubin/tap-summary">tap-summary</a></li> <li><a href="https://github.com/Hypercubed/tap-markdown">tap-markdown</a></li> <li><a href="https://github.com/gabrielcsapo/tap-html">tap-html</a></li> <li><a href="https://github.com/mcnuttandrew/tap-react-browser">tap-react-browser</a></li> <li><a href="https://github.com/dhershman1/tap-junit">tap-junit</a></li> <li><a href="https://github.com/MegaArman/tap-nyc">tap-nyc</a></li> <li><a href="https://github.com/Sceat/tap-spec-emoji">tap-spec (emoji patch)</a></li> <li><a href="https://github.com/rgruesbeck/tape-repeater">tape-repeater</a></li> <li><a href="https://github.com/Josenzo/tabe">tabe</a></li> </ol> </details>

Alternative startup:

By default, tappedout automatically runs tests. This behavior can be overridden by setting autostart to false, then manually invoking the start() method.

import test from 'tappedout'

test.autostart = false

test('title 1', t => { ... }})
test('title 2', t => { ... }})
test('title 3', t => { ... }})

test.start()

Overview: How to Make Simple/Awesome Tests

Really... you should read this section if you like making things easy on yourself.

The API is very simple, yet very powerful. There are some simple design principles that can make the experience of testing great. Write less code, more naturally.

  1. Directives TAP directives are special/optional "notes" in the output. There are only two options: skip and todo. These directives can be added/removed throughout the development lifecycle, making it easier to focus on the tests that matter. This can be really helpful as test suites grow. Many methods in this library support a directive option, and there are some special functions for applying directives in bulk (test.only and test.skip).<br/>

  2. Detailed Output Sometimes it is valuable to have detailed information about a particular test, such as info about why a test failed. The TAP protocol allows this to be embedded in the output, via YAML.<br/>

    Many of the methods in this library support key/value (JSON) arguments that will be properly embedded in the output.

    • failinfo() and expect() autocreate detail objects.
    • info() supports custom details.
    • All assertion/response methods support custom detail objects, wherever you see "object detail" as a method parameter.<br/>

    A key usability feature of this library is the ability to add a DISPLAY_OUTPUT attribute to detail objects. By default, passing tests do not output details, while non-passing tests do. To override this behavior, make sure the detail object has an attribute called DISPLAY_OUTPUT: true/false.

API

comment (string message [, object detail])

test('suite name', t => {
  t.comment('Comment goes here')
})
# Comment goes here

If the message is null, undefined, or blank, no output will be generated.

pass (string message [, string directive, object detail])

test('suite name', t => {
  t.pass('Looks good')
})
ok 1 - Looks good

The directive argument is optional. It accepts todo or skip.

fail (string message [, string directive, object detail])

test('suite name', t => {
  t.fail('Uh oh')
})
not ok 1 - Uh oh

The directive argument is optional. It accepts todo or skip.

failinfo (any expected, any actual, string message [, string directive])

This is the same as the fail method, but it will output a detail message in YAML format (per the TAP spec).

test('suite name', t => {
  t.failinfo(1, 2, 'Should be equal')
})
TAP version 13
# suite name
not ok 1 - Should be equal
  ---
  message: Unmet expectation
  severity: fail
  expected: 1
  actual: 2
  ...
1..1

info (object)

Additional test information can be embedded in TAP results via YAML. The info method accepts a valid key/value JSON object, which will be embedded in the output in YAML format.

test('suite name', t => {
  const passing = false

  t.ok(passing, 'test description')

  if (!passing) {
    t.info({
      message: 'Detail',
      got: {
        mytest: {
          result: false
        }
      },
      expected: {
        mytest: {
          result: true
        }
      }
    })
  }
})
TAP version 13
# suite name
not ok 1 - test description
  ---
  message: Detail
  got: {
    "mytest": {
      "result": false
    }
  }
  expected: {
    "mytest": {
      "result": true
    }
  }
  ...
1..1

skip (string msg [, object detail])

Skip the test. This serves primarily as a placeholder for conditional tests. To skip an entire test suite, see test.skip and test.only.

test('suite name', t => {
  t.skip('Not relevant to this runtime')
})
ok 1 # skip Not relevant to this runtime

todo (string message, [boolean pass = true, object detail])

TODO items are a special directive in TAP. They always "pass", even if a test fails, because they're [considered to be a work in progress](https://testa

Related Skills

View on GitHub
GitHub Stars8
CategoryDevelopment
Updated2y ago
Forks1

Languages

JavaScript

Security Score

75/100

Audited on Mar 14, 2024

No findings