In this little post we will be testing a new feature of nodeJS 18.
Node.js 18 will be promoted to Long Term Support (LTS) in October 2022.
For the Node.js 18 release, I'll highlight some of the new features.
Exciting new features include:
- Experimental Fetch
- Test Runner
- ECMAScript modules improvements
- Improved support for AbortController and AbortSignal
- Updated Platform Support
Among other features.
Today we are going to be doing some examples with testing where we will also be testing fetch, Array.findLast and Array.findLastIndex in a superficial way.
You can get all the code from this repository
Getting started
So let's create our package.json with the command:
npm init -y
Remember that you must install version 18 of node from the official page
Now we are going to create a file which will be the index.js where we are going to start writing our tests.
To start let's see what we have to import:
import test from "node:test";
import assert from "node:assert";
We see that we have 2 apis that come have to be prefixed to node:
or it won't work for you.
Once importing this we can now write our first test.
Test a string:
test("Testing a string", () => {
assert.match("Welcome Node 18", /Node 18/);
});
This test will give us the following output :
ok 1 - Testing a string
---
duration_ms: 0.000385918
...
First what we will do is use the tests method which receives the description as the first parameter and a callback as the second parameter which will have the logic of our test or we can even execute subtest as indicated in the official documentation
To assert a string we have to pass the string we want to test as the first parameter and as the second parameter we send the regular expression as we saw in the previous code.
We can also send a third parameter which is optional but will serve as a custom error message. Let's see the example:
test("Testing a string fails", () => {
assert.match("Hello", /world/, 'This string does not contain "world"');
});
This test will give us the following output :
β―node index.test.js
not ok 1 - Testing a string fails
duration_ms: 0.000888784
failureType: 'testCodeFailure'
error: 'This string not contains "world"'
code: ERR_ASSERTION
stack: |-
TestContext.<anonymous> (file:///Users/jordandev/Desktop/node18/index.test.js:5:10)
Test.runInAsyncScope (node:async_hooks:202:9)
Test.run (node:internal/test_runner/test:333:20)
Test.start (node:internal/test_runner/test:287:17)
Test.test (node:internal/test_runner/harness:126:18)
file:///Users/jordandev/Desktop/node18/index.test.js:4:1
ModuleJob.run (node:internal/modules/esm/module_job:198:25)
async Promise.all (index 0)
async ESMLoader.import (node:internal/modules/esm/loader:409:24)
async loadESM (node:internal/process/esm_loader:85:5)
...
tests 1
pass 0
fail 1
skipped 0
todo 0
duration_ms 0.062970366
As you can see in the error our custom error appears.
equal and notEqual
Now we will see the equal and notEqual methods which will allow us to test 2 values to know if they are equal and not equal:
test("Testing that a number is equal", () => {
let current = 99;
let expected = 99;
assert.equal(actual, expected);
});
test("Testing that a number is not equal", () => {
let current = 22;
let expected = 393;
assert.notEqual(actual, expected, `${actual} is not equal to ${expected}`);
});
As you can see, the 2 receive the current value as the first parameter and the expected value as the second parameter.
Remember to run the test with
node index.js
deepStrictEqual
We are going to test an object, for this we are going to use the deepStrictEqual method that will help us to deeply test the properties of our object:
test("Testing objects", () => {
assert.deepStrictEqual(
{ name: "jordan" },
{ name: "jordan" },
"Objects are not equal"
);
});
Testing asynchronous functionality
To test an asynchronous function we only have to use the asynchronous callback and in this way we can use await to be able to resolve promises:
test("Testing asynchronous functionality", async() => {
const number = await Promise.resolve(90);
assert.equal(number, 90, "The number is not equal to 90");
});
Array.findLast and Array.findLastIndex
Now we are going to try the Array.findLast method, what we will do is create an array of numbers from 1 to 10 and we will look for the last multiple of 3 and as a result we should obtain 9
test("Array.findLast", () => {
constant numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const lastmultipleofthree = numbers.findlast((n) => n % 3 === 0);
assert.equal(lastMultipleOfThree, 9);
});
The findLast method is similar in syntax to a filter but it will return the last element found.
Now we will see the operation of the Array.findLastIndex method, we will have an array with repeated numbers and we will look for the last index of the element that is equal to 3, in this case it should be 9 according to the array that we will pass to it.
test("Array.findLastIndex", () => {
const numbers = [1, 3, 2, 4, 4, 3, 4, 1, 9, 3];
const lastIndexOfThree = numbers.findLastIndex((n) => n === 3);
assert.equal(lastIndexOfThree, 9);
});
This works similar to findIndex but returns the last found index of an element based on the condition.
Fetch
Now we are going to try one of my favorite features which is fetch.
Let's make a call to the jsonplaceholder api endpoint https://jsonplaceholder.typicode.com/users/1
test("Fetch", async() => {
const reponse = await fetch("https://jsonplaceholder.typicode.com/users/1");
const json = await response.json();
assert.equal(json.name, "Leanne Graham");
});
As we can see we have the fetch functionality just as we would from the browser.
I have personally loved this and can't wait for it to be stable.
Subtests
Finally we are going to do a subtest so that you have an example of how to do it:
test("top level test", async (t) => {
await t.test("subtest 1", (t) => {
assert.strictEqual(1, 1);
});
await t.test("subtest 2", (t) => {
assert.strictEqual(2, 2);
});
});
This example is offered by the official nodejs documentation. As you can see, it is very easy to chain tests through the parameter that the callback gives you.
So having this clear, you can try out the new node. Personally, I really liked that they incorporate the test and node api.
We cannot fail to mention the new methods for Arrays that will surely be super useful.
If you want to know more about this update you can see it from the official blog here
Top comments (1)
Regarding test runner, unfortunately:
js
,mjs
,cjs
files, so it will miss.ts
specs when scanning folders."node:test"
module are missing in@types/node
.Currently we can write native tests in typescript and run them with
ts-node
, when we want to run bulk we can run those test withtape
library ("node:test"
will work) and watch mode can be done withnodemon
.