Testing 101 in JavaScript

Abir (@imabptweets)
JavaScript in Plain English
6 min readJun 7, 2021

--

A beginner-friendly guide to writing tests in JavaScript

“Have you ever encountered, a situation, where you have two functions, f1 and f2, and on running the script, you found f1 working as expected, but f2 is not working? So after few minutes of debugging, you finally fixed f2 and pushed the code! Wait, but did you recheck f1, whether it's working or not, after fixing f2?”

Edit: If you love to see video edition for the same, I will be coming up with the same, in next week on my Youtube.

Obviously, most of us do this mistake. And Junior Devs/ Student Developers like us, have learned from this mistake, but we still do it, but less frequently.

So today I will be discussing, with you about Testing in JavaScript and will be performing some live testing with you. Don’t worry, if you are just getting started, with testing. This will definitely, help you to know about testing.

What do you need? A Browser and an editor.

Lets taste(test)

There are a lot of techniques, for testing, we are going to use one of the techniques, known as Behavior Driven Development or BDD.

In simple words, it means,

  • We are going to have a function (we will be calling it a unit), and we will be having a test file, which will describe the tests, for that particular unit.
  • Next, we will make sure, that the tests fail, and then debug/re-implement the unit once again.
  • Finally, after debugging, we will verify that the latest implementation of the unit passes the tests successfully.
  • (Optional) Repeat the same stuff, for other units(here as functions).
Behavior Driven Development

“Writing test files, and performing tests, also known as automated testing in which tests are written separately, in addition to the code. They run our functions in various ways and compare results with the expected.”

So we are going to follow a practical approach to learn about the basics of testing.

We have to create a function pow(x,n) that returns, the value, x to the power of n.

“In Javascript, we do have an operator ** which does the work, but we are here to learn the basics of testing, henceforth, this will be our example, which makes sure, things are beginner-friendly.”

So before creating the code for the function, pow we are going to imagine what the function should do and describe it. This writing of description, also known as specification or specs. It is just another fancy word, which is just a way how we want to describe our test function, like its name or what the test does.

The following code snippet shows, how a specification for our pow function looks like.

describe("pow", function() {

it("raises to n-th power", function() {
assert.equal(pow(2, 3), 8);
});

});

Three things to note, there are three basic components of the specification.

  • describe("title", function() { ... }): We use this to describe the function/ unit we are going to test.
  • it("the-exact-use-case", function() { ... }): If you are completely new to this, use cases, means situations, or can be the actions. here our use case is raised to the nth power.
  • assert.equal(value1, value2): The code inside it the block, if the implementation is correct, should execute without errors. Functions assert.* are used to check whether pow works as expected.

Live Testing

We will be using the following famous JS Libraries, which provides us describe and it functions.

Mocha- the core framework: it provides common testing functions including `describe` and `it` and the main function that runs tests.

Chai – the library with many assertions. It allows us to use a lot of different assertions, for now, we need only assert.equal.

Next, now this will be a file system.

--directory
|___ index.html
|___ test.js

We will be having an index.html file with all our mochajs, and chaijs, imported. And we will be having test.js where we are going to do our BDD testing.

Your index.html should look like this.

<!DOCTYPE html>
<html>
<head>
<!-- add mocha css, to show results -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/mocha/3.2.0/mocha.css">
<!-- add mocha framework code -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/mocha/3.2.0/mocha.js"></script>
<script>
mocha.setup('bdd'); // minimal setup
</script>
<!-- add chai -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/chai/3.5.0/chai.js"></script>
<script>
// chai has a lot of stuff, let's make assert global
let assert = chai.assert;
</script>
</head>

<body>

<script>
function pow(x, n) {
/* function code is to be written, empty now */
}
</script>

<!-- the script with tests (describe, it...) -->
<script src="test.js"></script>

<!-- the element with id="mocha" will contain test results -->
<div id="mocha"></div>

<!-- run tests! -->
<script>
mocha.run();
</script>
</body>

</html>
  • Under the head tag, we have imported, the libraries needed.
  • Under the body tag, the first script defines our function pow which is right now empty.
  • Next, we are referencing our test.js file.
  • A div with id as mocha will help mochaJS, to show the output
  • In the end, the tests are started by the command mocha.run()

If you run index.html you will be seeing something similar like this.

Initial Implementation of the Unit

So as said earlier, the function pow we will be calling a unit. So initially, we are implementing the code like this.

function pow(x, n) {
return 8;
}

And test.js containing, the following test.

describe("pow", function() {  it("raises to n-th power", function() {
assert.equal(pow(2, 3), 8);
});
});

Refresh the browser, and you can see an output similar to this.

Here if you see, the test is successful, we are just having one test case, but the pow function is completely a cheat, as it returns 8 for every value of x. So we need to improve on the specs or in other words, the test.js

Improving the spec

As we know, we have done a cheat in our pow function. So we will be using the test.js file to show us, the failing tests.

Let’s go to the test.js file, and improve our spec to the following.

describe("pow", function() {  it("2 raised to power 3 is 8", function() {
assert.equal(pow(2, 3), 8);
});
it("3 raised to power 4 is 81", function() {
assert.equal(pow(3, 4), 81);
});
});

Saving the test.js file, and refresh your browser, you will be certainly getting something similar to this.

Debugging the unit

Now it’s time to re-implement the function pow. Head over to index.html and under script tag, write the following code.

function pow(x, n) {
let result = 1;
for (let i = 0; i < n; i++) {
result *= x;
}
return result;
}

So we have improved our implementation, lets refresh our browser. And if all the debugging done correctly, you are going to see something like this.

And yes we have successfully, tested our code. But still, there is a lot to improve in the specification. The following specification should be the more precise one to follow.

describe("pow", function() {  function makeTest(x) {
let expected = x * x * x;
it(`${x} in the power 3 is ${expected}`, function() {
assert.equal(pow(x, 3), expected);
});
}
for (let x = 1; x <= 5; x++) {
makeTest(x);
}
});

Refresh your browser, and you are certainly, going to see the following output.

Congratulations 🎉🎉🎉

“Finally, you made it. Testing is the most important phase in software engineering, it helps to write good and maintainable software. Also, when you contribute to various open-source organizations and in fact even working as a junior developer or Software Engineering Intern, you are supposed to write, test cases, for your code.”

More content at plainenglish.io

--

--

I love to build,innovate and write about software from its scalability to its design. Also passsionate about Dev-Advocacy. DMs open: twitter.com/imabptweets