a TAP producer for JavaScript unit testing
Testing a syncronous function
// add.spec.js
import { test } from "fvb"
import { add } from "./add.js"
test("Test add function", t => {
t.equal(add(1, 2, 3, 4, 5, 6, 7), 28, "given multiple arguments")
t.equal(add([1, 2, 3]), 6, "given an array")
// t.plan is an OPTIONAL assertion that verifies the assertion count
t.plan(2)
})
Running the test with node
.js
node add.spec.js
Testing async functions
// test-a.js
import { test } from "fvb"
test("Testing another async function in a different file", async t => {
t.equal(await Promise.resolve(parseInt("1001001", 2)), 73)
t.notEqual(await Promise.resolve(0), -0)
t.plan(2)
})
Running the test
node test-a.js
When calling the test
function multiple times in a single file and
testing async code, top-level await should be used for the tests to run
in order and for t.plan
to work properly.
// test-b.js
import { test } from "fvb"
await test("Testing async function", async t => {
t.equal(await Promise.resolve("Hello"), "Hello")
t.plan(1)
})
await test("Testing another async function", async t => {
t.equal(await Promise.resolve(42), 42)
t.plan(1)
})
Running the test
node test-b.js
Use top-level await
to ensure that the t.plan
method works and the
tests run in the expected order.
// index.spec.js
await import("./test-a.js")
await import("./test-b.js")
Running the tests
node index.spec.js
pnpm
pnpm add --save-dev fvb
npm
npm install --save-dev fvb
yarn
yarn add --dev fvb
test :: String -> (T -> Undefined) -> Promise(T)
The test
method is the only function provided by fvb
. It accepts a
string value for the test description as the first argument. The second
argument is a function that accepts a T
interface as described in the
Assert section below. A Promise containing T
is returned.
t#equal :: a -> b -> (String | Undefined) -> Undefined
A [deep] equality assertion that checks if actual
is equal to
expected
using JavaScript's Object.is
static method. Setoid
objects with an equals
or fantasy-land/equals
method are compared
using these methods.
t#notEqual :: a -> b -> (String | Undefined) -> Undefined
This assertion is the same as the t.equal
method except the values
compared are expected to be NOT equal.
t#ok :: a -> (String | Undefined) -> Undefined
Pass if the given value
is true
.
t#notOk :: a -> (String | Undefined) -> Undefined
Pass if the given value
is false
.
t#throws :: (() -> Undefined) -> (String | Undefined) -> Undefined
Pass if the given function
throws when called.
t#doesNotThrow :: (() -> Undefined) -> (String | Undefined) -> Undefined
Pass if the given function
does NOT throw when called.
t#plan :: Integer -> Undefined
The t.plan
module is NOT required. It is just another check that can
be used to help ensure all of the assertions ran. The integer given
should be a count of the assertions in the current test
(excluding
the current t.plan call).
When using this method for testing asynchronous functions, be sure to
await
any async
calls before calling t.plan
.
t#fail :: (String | Undefined) -> a -> b -> Undefined
An assertion that automatically fails. Useful as a helper to build custom assertions.
t#pass :: (String | Undefined) -> Undefined
An assertion that automatically passes. Useful as a helper to build custom assertions.
t#comment :: String -> Undefined
Print the given message as a comment in the TAP output.
t#bail :: (String | Undefined) -> Undefined
Bail out of the test! If the environment has a process.exit
method
then it is called, otherwise an Error
is thrown.
test
returns a Promise containing T
. This can be useful for creating
custom reporting and for using in the browser's console
.
import { test } from "https://cdn.skypack.dev/fvb"
const element = document.querySelector("#test-element")
test("Element exists", t => {
t.notEqual(element, null, "#test-element should exist in document")
t.plan(1)
})
.then(t => {
console.log("TAP version 14")
console.log(`1..${t.total}`)
console.log(t.body)
})