Testing is an important part of application and software development. It ensures that our web apps function and work as expected.
In the JavaScript ecosystem, we have multiple testing libraries and frameworks, and today, we’ll be looking at Baretest, a new, minimalistic testing library that considers itself an alternative to Jest.
Baretest is a minimal, fast, and simple JavaScript test runner. In this modern software development era, where speed is very important, Baretest boasts of incredible speed as compared to Jest.
You can install it from npm:
npm i --save-dev baretest
And use it as such:
const test = require('baretest') assert = require('assert')
Baretest, being a minimalistic library, makes use of Node’s assert library. The assert
module is a testing library in-built to Node with several methods for asserting passed arguments and statements. Baretest mainly act as a wrapper, while the real test is done with by the assert
module.
The Baretest library has a number of methods:
test(name, fn)
This method initializes a test suite with the test’s name and corresponding function. For example, if we want to test that 1 is equal to 1, the following code helps us do so:
const test = require('baretest') assert = require('assert') test('Proove that 1 == 1', () => { assert.ok(1 == 1) })
test.only(name, fn)
The .only(name, fn)
method accepts a name for the test and a function that contains the test itself. The method is used to instruct the test runner to run only this test and ignore the others.
Say, for example, we want to test a sum function, but we do not want to run other tests alongside it. We simply use the .only(name, fn)
method, as in the example below:
const test = require('baretest') assert = require('assert') test('Proove that 1 == 1', () => { assert.ok(1 == 1) }) test.only('1 + 1 should equal 2', () => { assert.equal(1+1, 2) })
When the above test is run, the sum test is the only one that is executed.
test.before(fn)
This method accepts a function as an argument. This function is executed before all supplied tests. For example:
test.before(() => { console.log("Yay! We're about to start!") })
test.after(fn)
This method accepts a function as an argument, and just like .before(fn)
, it executes after the supplied tests have finished running. For example:
test.after(() => { console.log("It was a successful test!") })
test.skip(name, fn)
This method is used to skip test cases and is useful for temporarily omitting tests.
test.run()
This method is invoked after writing all tests cases. The method runs the supplied tests in the test file:
const test = require('baretest') assert = require('assert') test.before(() => { console.log("Yay! We're about to start!") }) test('Proove that 1 == 1', () => { assert.ok(1 == 1) }) test('1 + 1 should equal 2', () => { assert.equal(1+1, 2) }) test.after(() => { console.log("It was a successful test!") }) // Run test! test.run()
So we’ve briefly discussed the methods in the Baretest library. In this section, we will be testing some simple stack operations.
First, we’ll build the Stack
data structure and then write tests for its operations. If you don’t know what a stack is, you should read this article on Data Structures.
First, we will create a folder, initialize it with npm, and then create the files needed for our test activity:
mkdir baretest & cd baretest npm init -y & npm i --save-dev baretest touch {stack, test}.js
Next, we implement the Stack
data structure:
class Stack { constructor() { this.items = []; } push(item) { this.items.push(item); } pop() { return this.items.length == 0 ? "Not enough items!" : this.items.pop() } peek() { return this.items[this.items.length - 1]; } isEmpty() { return this.items.length > 0 ? false : true } clear() { while (this.items.length != 0) { this.items.pop() } } length() { return this.items.length } } module.exports = new Stack()
Having implemented our data structure, we move on to writing our test. We will be testing the push()
, pop()
, and length
methods.
test.js
First, we import baretest
, the assert
module, and the stack:
const test = require('baretest')('Stack Operation Testing'), assert = require('assert') books = require('./stack')
Next, we write a test for our .push()
, .pop()
, .peek()
, and .length()
methods:
test('Add a new book', () => { books.push("Engineering Maths") assert.equal(books.peek(), "Engineering Maths") })
In the test above, we pushed a new book into our books stack and confirm using the assert.equal()
method. We will be using the assert.equal()
method subsequently.
Next, we remove the book using the .pop()
method and confirm that the length of our stack is 0:
test('Remove the book', () => { books.pop() assert.ok(books.length() == 0) })
In the code above, we used the assert.ok()
method that tests whether a given expression is true.
Next, we add a new book and write another test to ascertain that the stack’s top element doesn’t point to the passed value:
test('Add another book', () => { books.push("Engineering Thermodynamics") assert.equal(books.peek(), "Engineering Thermodynamics") }) test('Shoud false', () => { assert.notStrictEqual(books.peek(), "Engineering Maths") })
We used the .notStrictEqual()
method to show that the top of the stack isn’t equal to “Engineering Maths.”
Next, we add a random book and test to confirm the length of the stack:
test('Add a random book', () => { books.push("Random book") assert.equal(books.peek(), "Random book") }) test('Confirm stack length', () => { assert.ok(books.length() == 2) })
We have now completed the tests for basic operations. The failing of these tests above means that our implementation is wrong or we have made a mistake somewhere. If the result is not as expected, you can use the errors thrown in the console for guidance.
Finally, we call the .run()
method:
test.run()
The next step is to run the test file to see the outcome of our tests:
node test.js
The speed of the test is really superb!
Baretest considers itself an alternative to Jest and in this section, we’re going to discuss some of the differences between these libraries under three major factors:
The time it took Baretest to run the test above is:
To determine the timing in Jest, we will have to write the test cases in the Jest wrappers, too. First, we will install Jest as a dev dependency:
npm install --save-dev jest
Next, we’ll create a test file for Jest and then write our tests:
touch jest.test.js
jest.test.js
const books = require('./stack') // Describe the tests. describe('Test the stack data structure implementation', () => { beforeAll(() => { books.clear() }) test('Add a new book', () => { books.push("Engineering Maths") expect(books.peek()).toBe("Engineering Maths") }) test('Remove the book', () => { books.pop() expect(books.length()).toBe(0) }) test('Add another book', () => { books.push("Engineering Thermodynamics") expect(books.peek()).toEqual("Engineering Thermodynamics") }) test('Should return false', () => { expect(books.peek()).not.toEqual("Engineering Maths") }) test('Add a random book', () => { books.push("Random book") expect(books.peek()).toBe("Random book") }) test('Confirm stack length', () => { expect(books.length()).toBe(2) }) })
To run our Jest test, we need to modify the test
command under scripts
in the package.json
file:
"test": "jest jest.test.js"
Next, we run our tests:
npm run test
One noticeable behavior is Jest’s startup time.
From the screenshot above, it took Jest 12.923 seconds to run the same test that Baretest ran in 0.178 seconds.
This article should give you a basic understanding of what Baretest is and what it’s capable of. The major win for Baretest is its speed, as it depends on Node’s assert
module to execute test cases. However, Baretest lacks complex features and, as a result, cannot be used for large-scale coverage tests.
On the other hand, Jest has the complex features but drags a bit even in the smallest test case. Since Baretest is still under active development, more features are expected to be added, and who knows if it might overtake Jest in the coming years? You can find all the code used in this article here.
Deploying a Node-based web app or website is the easy part. Making sure your Node instance continues to serve resources to your app is where things get tougher. If you’re interested in ensuring requests to the backend or third-party services are successful, try LogRocket.
LogRocket is like a DVR for web and mobile apps, recording literally everything that happens while a user interacts with your app. Instead of guessing why problems happen, you can aggregate and report on problematic network requests to quickly understand the root cause.
LogRocket instruments your app to record baseline performance timings such as page load time, time to first byte, slow network requests, and also logs Redux, NgRx, and Vuex actions/state. Start monitoring for free.
Hey there, want to help make our blog better?
Join LogRocket’s Content Advisory Board. You’ll help inform the type of content we create and get access to exclusive meetups, social accreditation, and swag.
Sign up nowJavaScript’s Date API has many limitations. Explore alternative libraries like Moment.js, date-fns, and the new Temporal API.
Explore use cases for using npm vs. npx such as long-term dependency management or temporary tasks and running packages on the fly.
Validating and auditing AI-generated code reduces code errors and ensures that code is compliant.
Build a real-time image background remover in Vue using Transformers.js and WebGPU for client-side processing with privacy and efficiency.