Jest and the Art of Testing: Adding Fun to Your Testing Journey — I
Testing is often seen as a serious and technical aspect of software development. However, that doesn’t mean testing can’t be fun! In this blog post, we’ll explore how Jest, a powerful JavaScript testing framework, can add an element of fun to your testing journey. We’ll dive into some creative and playful testing techniques, share amusing examples, and highlight Jest’s features that can inject a dose of enjoyment into your testing process.
Jest[1] is a JavaScript testing framework built on top of Jasmine[2] and maintained by Meta (formerly Facebook). It was designed and built by Christoph Nakazawa with a focus on simplicity and support for large web applications. It works with projects using Babel, TypeScript, Node.js, React, Angular, Vue.js and Svelte. Jest doesn’t require a lot of configuration for first-time users of a testing framework. — — Wikipedia
Jest offers a comprehensive and developer-friendly approach to writing tests. It provides an intuitive API for defining test cases, supports mocking and assertion functionalities, handles asynchronous testing scenarios, and generates detailed code coverage reports.
Step1: Setting Up Jest
- Install Jest as a development dependency.
npm install --save-dev jest
- Add the following section to your
package.json
:
{
"scripts": {
"test": "jest"
}
}
Step2: Create the test
- Create a file containing both function and test with
test.js
extension. For example, let’s create a file calledmultiply.test.js
.
// multiply.test.js
function multiply(a, b) {
return a * b;
}
test('multiply 1 * 2 to equal 2', () => {
expect(multiply(1, 2)).toBe(2);
});
In the test file, you define your tests using the test
function provided by Jest. The first argument is a string that describes the test case, and the second argument is a function that contains your test logic.
The expect
function is used to make assertions about your code's behavior. In this example, we expect the multiply
function to return 2
when called with arguments 1
and 2
.
Step3: Run the test
- To run your tests, execute the following command in your terminal:
npm test
Step4: Check the Result
- If the test did pass, you would get the following message in your terminal:
> test
> jest
PASS ./multiply.test.js
✓ multiply 1 * 2 to equal 2 (1 ms)
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 0.32 s
Ran all test suites.
- If the test didn’t pass, you would following:
> test
> jest
FAIL ./multiply.test.js
✕ multiply 1 * 2 to equal 2 (4 ms)
● multiply 1 * 2 to equal 2
expect(received).toBe(expected) // Object.is equality
Expected: 3
Received: 2
4 |
5 | test('multiply 1 * 2 to equal 2', () => {
> 6 | expect(multiply(1, 2)).toBe(3);
| ^
7 | });
at Object.toBe (multiply.test.js:6:28)
Test Suites: 1 failed, 1 total
Tests: 1 failed, 1 total
Snapshots: 0 total
Time: 0.359 s, estimated 1 s
Ran all test suites.
Essential Matchers and Assertions
When you’re writing tests, you often need to check that values meet certain conditions expect
gives you access to a number of "matchers" that let you validate different things.
.toBe(value)
By using .toBe
, you can compare primitive values or check the referential identity of object instances. Ps, do not use .toBe
with floating-point numbers, instead, use .toBeCloseTo
.
.toBeCloseTo(number, numDigits?)
You can use .toBeCloseTo
to compare float for approximate equality. For example:
test('adding works sanely with decimals', () => {
expect(0.2 + 0.1).toBe(0.3); // Fails!
});
● adding works sanely with decimals
expect(received).toBe(expected) // Object.is equality
Expected: 0.3
Received: 0.30000000000000004
15 |
16 | test('adding works sanely with decimals', () => {
> 17 | expect(0.2 + 0.1).toBe(0.3); // Fails!
| ^
18 | });
at Object.toBe (multiply.test.js:17:23)
Test Suites: 1 failed, 1 total
Tests: 1 failed, 2 passed, 3 total
Snapshots: 0 total
Time: 0.379 s, estimated 1 s
Ran all test suites.
shiyaozhai@shiyaos-imac Jest-Demo %
But if you use .toBeCloseTo
, it will pass the test.
test('adding works sanely with decimals', () => {
expect(0.2 + 0.1).toBeCloseTo(0.3, 5);
});
.toBeTruthy()
and .toBeFalsy()
When you don’t care about the value but just want to ensure in a boolean context, you can always use .toBeTruthy()
or .toBeFalsy()
. For example:
test('isFalsyValue should return false for truthy values', () => {
expect(isFalsyValue(true)).not.toBeFalsy();
}
.toContain(item)
You can use .toContain
to check if an item is in an array. It is case-sensitive.
test('the flavor list contains lime', () => {
expect(getAllFlavors()).toContain('lime');
});
.toThrow(error)
Use .toThrow
to test that a function throws when it is called.