minispec
TypeScript icon, indicating that this package has built-in type declarations

1.3.0 • Public • Published

MiniSpec

Lightweight test/spec execution engine for TypeScript and JavaScript

MiniSpec is a lightweight test/spec execution engine for TypeScript and JavaScript, inspired by RSpec and minitest.

It works out-of-the-box with CommonJS, ESM and TypeScript.

Its purpose is to remain lightweight, without any runtime dependency and really low number of development dependencies.

Table of Content

Why another test/spec execution engine?

The idea of MiniSpec came from the need to write some unit-tests for a tiny library written in TypeScript. All testing framework were pretty big - with a lot of dependencies - and may not work well out-of-the-box with TypeScript.

MiniSpec goal is to remain lightweight, without runtime dependency. Its main purpose is to add a bunch of tests to small JavaScript or TypeScript projects.

Its name comes from the combination of minitest, and RSpec. Minitest for the idea of having a small and easy to maintain test/spec engine. RSpec for the spec syntax and for some output formats.

Why does weight matter?

Less dependencies and a lightweight library means less resources consumed while downloading it and executing it. It also reduces the potential attack surface.

That means also fewer features. That is why MiniSpec purpose is to be used with small projects, which do not need advanced testing capabilities offered by more popular alternatives.

What's new in version 1.3.0

While full changelog is available in the repository, here's what's new in v1.3.0:

  • Added

    • Official support for Chai Assertion Library: while Chai was already working fine with MiniSpec, its support is now enforced via automated integration tests. That means also that if you are facing any issue using Chai with MiniSpec, you can report it and we'll do our best to fix it.
    • Support for Node.js v22
  • Changed

    • [Internal] Bump development dependencies
    • [Internal] Usage of npm workspaces to manage examples and integration tests
    • Bump dependencies from the various examples
  • Deprecated

    • Support for Node.js v16 is deprecated and will be dropped with next major version of MiniSpec: v2.0

Usage

Installation

To install MiniSpec, add it to your dev dependencies:

$ npm install --save-dev minispec

or with yarn:

$ yarn add minispec --dev

Check install

To make sure it is working as expected, create a file named validate_minispec_install.mjs in your project root directory:

// validate_minispec_install.mjs

import assert from 'assert'
import MiniSpec, { describe, it } from 'minispec'

describe('minispec', async () => {
  it('is working', async () => {
    assert.ok(true)
  })
})

MiniSpec.execute()

Then run the following:

$ node validate_minispec_install.mjs

The expected output should look like the following:

minispec
  is working

Finished in 3 milliseconds (discovering took 1 milliseconds, execution took 2 milliseconds)
1 test, no failure 👏

Congrats, MiniSpec is working fine! You can delete the file validate_minispec_install.mjs and start writing your own specs.

Writing tests

Due to its nature, MiniSpec comes with less magic than other test framework. You'll have to write a little bit of code to set it up. But don't worry, nothing complicated: only basic JavaScript/TypeScript.

The big picture

In a typical setup, you'll have an entrypoint for MiniSpec which will be responsible for loading MiniSpec, importing your tests, configuring your test environment, then executing the tests.

The following examples illustrates it in TypeScript, and in JavaScript using es Modules and CommonJS

In TypeScript

// ./specs/minispec_entrypoint.ts

import MiniSpec from 'minispec'

import './calculator_spec'

MiniSpec.execute()

Then your test files may look like the following:

// ./specs/calculator_spec.ts

import assert from 'assert/strict'
import { describe, context, beforeEach, it } from 'minispec'

import Calculator from '../src/calculator'

describe('Calculator', async () => {
  let calculator: Calculator

  beforeEach(async () => {
    calculator = new Calculator()
  })

  describe('.sum(a, b)', async () => {
    context('when a and b are valid numbers', async () => {
      const a = 40
      const b = 2

      it('returns the sum of a and b', async () => {
        assert.equal(calculator.sum(a, b), 42)
      })
    })
  })
})

Assuming the following calculator:

// ./src/calculator.ts

export default class Calculator {
  constructor() {}
  sum(a: number, b: number): number {
    return a + b
  }
}

You can then build and run your tests:

$ npx tsc src/*.ts specs/*.ts --module CommonJS --esModuleInterop true --rootDir "." --outDir "./dist"
$ node ./dist/specs/minispec_entrypoint.js

You can also make it part of your package scripts in your package.json:

{
  "scripts": {
    "build:specs": "tsc src/*.ts specs/*.ts --module CommonJS --esModuleInterop true --outDir './dist'",
    "test": "npm run build:specs && node ./dist/specs/minispec_entrypoint.js"
  }
}

Now you can run your tests using:

$ npm test

MiniSpec is also compatible with EcmaScript modules (es5, es6, esnext, ...), and ts-node. It relies only on your own usage and configuration of TypeScript.

Using ECMAScript modules (esm)

// ./specs/minispec_entrypoint.js

import MiniSpec from 'minispec'

import './calculator_spec.js'

MiniSpec.execute()

Then your test files may look like the following:

// ./specs/calculator_spec.js

import assert from 'assert/strict'
import { describe, context, beforeEach, it } from 'minispec'

import Calculator from '../src/calculator.js'

describe('Calculator', async () => {
  let calculator

  beforeEach(async () => {
    calculator = new Calculator()
  })

  describe('.sum(a, b)', async () => {
    context('when a and b are valid numbers', async () => {
      const a = 40
      const b = 2

      it('returns the sum of a and b', async () => {
        assert.equal(calculator.sum(a, b), 42)
      })
    })
  })
})

Assuming the following calculator:

// ./src/calculator.js

export default class Calculator {
  constructor() {}
  sum(a, b) {
    return a + b
  }
}

You can then run your tests:

$ node ./specs/minispec_entrypoint.js

You can also make it part of your package scripts in your package.json:

{
  "scripts": {
    "test": "node ./specs/minispec_entrypoint.js"
  }
}

Now you can run your tests using:

$ npm test

Using CommonJS

// ./specs/minispec_entrypoint.js

const MiniSpec = require('minispec').default

require('./calculator_spec.js')

MiniSpec.execute()

Then your test files may look like the following:

// ./specs/calculator_spec.js

const assert = require('assert').strict

const { describe, context, beforeEach, it } = require('minispec')
const Calculator = require('../src/calculator.js').default

describe('Calculator', async () => {
  let calculator

  beforeEach(async () => {
    calculator = new Calculator()
  })

  describe('.sum(a, b)', async () => {
    context('when a and b are valid numbers', async () => {
      const a = 40
      const b = 2

      it('returns the sum of a and b', async () => {
        assert.equal(calculator.sum(a, b), 42)
      })
    })
  })
})

Assuming the following calculator:

// ./src/calculator.js

exports.default = class Calculator {
  constructor() {}
  sum(a, b) {
    return a + b
  }
}

You can then run your tests:

$ node ./specs/minispec_entrypoint.js

You can also make it part of your package scripts in your package.json:

{
  "scripts": {
    "test": "node ./specs/minispec_entrypoint.js"
  }
}

Now you can run your tests using:

$ npm test

Picking an assertion library

MiniSpec should work well with any assertion library. Yet it provides official support for the Node.js built-in assert one, and also for chai.

Node.js built-in assert

The Node.js built-in assertion library is simple, yet far enough for small projects where MiniSpec may be used. Remember: MiniSpec is designed for small projects which just requires a bunch of tests. Node.js assert library is also perfect in such case!

Chai Assertion Library

Chai is a BDD/TDD assertion library which remains relatively lightweight and offer more assertions, but mostly 3 styles: assert, expect and should.

MiniSpec officially supports Chai since version 1.3.0. It means that if you are facing issues integrating Chai with MiniSpec, you can report it and we'll do our best to find a fix or a workaround.

More documentation

To go further, you can follow the documentation:

Package Sidebar

Install

npm i minispec

Weekly Downloads

24

Version

1.3.0

License

MIT

Unpacked Size

218 kB

Total Files

100

Last publish

Collaborators

  • kao98