Baretest — A minimal alternative to Jest

Baretest is a fast and simple JavaScript test runner. It offers near-instant performance and a brainless API. It’s a minimal alternative to Jest.

Github Project Page ->

Why Baretest?

The primary reason for building Baretest was to get near-instant unit tests. We constantly hit CMD + B on Sublime Text to test a function we are actively working on. We do this all the time, sometimes hundreds of times a day. If the test takes seconds to run our flow suffers and the frustration levels start to rise.

using baretest
Using Baretest to test Baretest

Here’s the difference when running the same test file with Jest and Baretest.

 

Same test: Jest performance: 3.84s. Baretest: 0.09s.

Sometimes Jest took seven seconds to start on a regular laptop. This is not acceptable for our style of unit testing, where everything above 100ms is considered slow.

It’s easy to use

We think a good test runner stays out of your way. We want to focus on the task at hand and not deal with the complexities of testing.

const test = require('baretest')('Test desc'),
  assert = require('assert'),
  app = require('my-app')

test('add user', async function() {
  const user = await app.addUser('test@cc.com')
  assert.equals(user.name, 'Test')
})

test('reject duplicate emails', async function() {
  await assert.rejects(async function() {
    await app.addUser('duplicate@address.com')
  })
})

// ... 
Node’s assert library has everything we need

The test() and assert.equals() methods are typically 98% of what we use when writing tests. We’ve never needed automatic re-ordering, file watchers, “mocking” or “snapshotting”. We want our test runner to be as invisible as possible. We don’t want to commit to a massive framework that dictates our work.

baretest_output
Short and sweet output

It’s minimalistic

Baretest is built in minimalistic fashion. It has under 50 lines of code and only one dependency (with 12 lines). In contrast, Jest is 57,540 lines of TypeScript and it has 76 dependencies. There are 1,745 files on the repository and a whopping 119,624 lines of code in total. And it’s just a test runner.

Move right and you get more features, complexity, and NPM dependencies.

Baretest is stripped down to bare essentials so if you need advanced stuff like parallelization, coverage reports, or mock functions, then Baretest is a bad choice.

Getting Started

Install Baretest using npm:

npm install --save-dev baretest

Let’s start by creating a simple app called sum.js:

module.exports = function(a, b) {
  return a + b
}

Then, create tests for it in a file named test.js

const test = require('baretest')('Sum tests'),
  assert = require('assert'),
  sum = require('./sum')

test('1 + 2', function() {
  assert.equal(sum(1, 2), 3)
})

test('2 + 3', function() {
  assert.equal(sum(2, 3), 5)
})

test.run()

Finally, run node test and Baretest will print this:

node test
sum    2

Done. Your first test using Baretest.

Test suites

With Baretest you can organize your tests programmatically with JavaScript giving you fine-grained control. For example:

const test = require('baretest')('My app'),
  assert = require('assert'),
  app = require('my-app')

require('./test/users')(test, assert, app)
require('./test/teams')(test, assert, app)
require('./test/sharing')(test, assert, app)
require('./test/commenting')(test, assert, app)
require('./test/billing')(test, assert, app)
// require('./test/mailer')(test, assert, app)
// require('./test/management')(test, assert, app)

!(async function() {
  await test.run()
})()
Use JavaScript to construct your suites

Error handling

Errors are pretty printed with color:

> node test

Bareserver • • • • • • • • • •
FAIL: “Raw handlers”

ReferenceError: bareserver.raw is not defined

TypeError: Cannot set property ‘b’ of undefined

at Object.<anonymous> (tools/bareserver/test.js:101:11)

at Object.self.exec (tools/bareserver/lib/index.js:71:22)

at processTicksAndRejections (internal/process/task_queues.js:97:5)

at async Object.fn (tools/bareserver/test.js:108:15)

API reference

test(name, fn)

Runs a function that contains the expectations to test. The first argument is the test name, which is shown when the test function fails.

test.only(name, fn)

Run only these tests and ignore the rest

// test the actively developed function
test.only('add team', async function() {
  const team = await app.addTeam('Acme Inc.')
})

test.before(fn)

Run the given function before all the supplied tests.

// remove all data prior each run
test.before(async function() {
  await app.cluster.clearAll()
})

test.after(fn)

Run the given function when there is a failure or after all the tests have passed.

test.skip(name?, fn?)

Skip the given function. Useful for omitting tests temporarily.

// ignore slow, broken, or incomplete stuff
test.skip('invite a friend', async function() {

})

test.run()

Run all the supplied tests.

Frequently asked questions

Why compare to Jest specifically?

Jest is currently the most popular option and developers seem to value its speed and ease of use. Baretest is an alternative for developers who (actually) value performance and usability.

Isn’t Jest fast in --watch mode?

It’s not. It took 1.566s to run the “sum” function on my laptop. Jest also says “estimated 2s”, but we don’t know what that means.

Why not make testing 🎉🎉😊🎉😍 fun?

Designing software might be fun, but we don’t get such emotions with testing.

Why care about the size?

We want to keep Baretest small because small things are easier to maintain and they have faster startup times, which is essential for our unit tests. And it’s not that we are too picky about the size, but there must be at least some limits to what is acceptable.

jest-vs-baretest 2
Jest has over 1,000 times more code

Why not use arrow functions?

We think old school function declarations are clearer, especially with the async keyword. We prefer to be explicit. Or maybe we are just old farts.

Where is this project heading?

Our first milestone is a permanent version with Long Term Support (LTS) that remains unchanged for many months, possibly years. This reduces the risk, expense, and disruption of deployment.

Who are you?

We are Volument. We use Baretest to revamp website analytics.