Skip to content

Latest commit

 

History

History
186 lines (104 loc) · 10.4 KB

README.md

File metadata and controls

186 lines (104 loc) · 10.4 KB

Ironhack Logo

Unit Testing - Guided example


Iteration 1 - Initial Setup

Fork this repository first. After you have successfully forked the repository to your account clone it to your machine.

Iteration 2 - Exploring the project

At the root of this project you'll find multiple files that are worthy of notice.

First, package.json. This files contains the external dependencies necessary to make the project work, as well as the configurations necessary to run our unit tests. Plus, it holds a set of custom scripts that we can run using the npm run command. You won't have to change the contents of this file.

Second, you will find a tests directory. This directory contains multiple files with the .spec.js extensions. It is common to name unit test files ending with a .spec.js or .tests.js extension.

Third, our main working file, calculator.js. It contains four distinct functions, one for each of the basic arithmetic operations. The functions sum, subtract and divide are incomplete. Later in the lab, you'll be asked to work on each to meet specific requirements. The fourth function, multiply, is implemented. You'll be asked to create unit tests to ensure that it runs as expected. At the bottom of this file you'll find an unfamiliar syntax (reading module.exports = /* ... */). It is required to make our unit tests work, and you'll be learning more about it later on.

Files such as package-lock.json (you don't see it just yet, but soon you will), and directories such as .github and node_modules (also, you don't see it just yet, but soon you will) are not relevant right now. By the end of this bootcamp, you will know much more about all these terms that probably don't make too much sense now. Patience 🙏

Iteration 3 - Setting up the project

Open your terminal.

To run our unit tests on your machine, you must have both Node.js and npm installed. You can ensure you have both by running the following commands:

$ node -v
# and
$ npm -v

As a result, you should see the versions of either installed on your machine.

As stated, our package.json file holds a list of the dependencies for this project. However, these dependencies are not automatically fetched when you clone the repository into your machine. To fetch and install the project's dependencies, follow the instructions below:

# after you cloned this guided example, navigate inside the repo
$ cd unit-testing-guided-example
# and install project dependencies
$ npm i

After this point, you will see that a new file has been created (package-lock.json) as well as new folder (node_modules) but no changes will be made from your side inside there so no need to dig deeper into it for now.

Iteration 4 - Running unit tests, seeing failures

Before working on any of the functionalities that we intend to unit test, let's run the npm run test command on our terminal.

# in the root of this project
$ npm run test

Image of terminal with failing test results

There should be two distinct forms of output. First, your terminal should display a list of the failed unit tests. Second, a file named lab-solution.html should be automatically generated at the root of the project. Opening this file will display the results of the unit tests in the browser.

‼️ If you get a message that reads "jest: command not found", you might have skipped the previous step where we installed dependencies using npm install.

Image of browser with failing test results

Since we don't want to have to run these tests every time we make changes to our solution, we can start the test-runner in "watch mode". That means that jest will be looking for changes in our code, and will re-run the automated tests every time you save a file. To run the test-runner in "watch mode", run the npm run test:watch command in your terminal.

$ npm run test:watch

To see the results of the unit tests being updated automatically in the browser window, you can use the VSCode extension "Live Server" to open the lab-solution.html file.

Iteration 5 - Passing our first tests

To pass the first tests, open the calculator.js file and complete the sum function.

If you simply return a sum of both arguments from the sum function, you should see at least the first two tests of the "Sum" suite passing. However, a few other tests in the test suite are failing.

For this particular sum function, we don't expect it to simply sum any two values that it is passed. We want a few edge cases to be considered an properly handled.

  • If the function is called with a single number, and no second argument is passed, the function should act as if the second argument passed equals 0.
  • If the function is called without any arguments, the function should act as if both arguments passed equal 0.

Iteration 6 - Subtracting

The subtract function follows the same logic. Complete it, and check the results of the unit tests to ensure that all of the requirements are met.

Iteration 7 - Dividing

In maths, we cannot divide a number by 0. However, if you perform a division operation in JavaScript, the value returned is Infinity.

JavaScript takes a relaxed approach on this topic, but we don't want to allow our divide function to make this mistake. As such, if the user calls the function divide and passes a 0 as the second argument, you should "throw" an error with the message "Cannot divide by 0".

To throw an error in JavaScript, you should write:

throw new Error('An explanatory error message');

Our divide unit tests will experiment with dividing plain integers, floating point numbers, but also dividing by 0. If this edge case is not considered, the last test of the test suite will fail.

Bonus: Iteration 8 - Creating our own tests

Up until now, we've been coding our functions to pass our tests. What we've been unknowingly doing is following a testing methodology called "Test-Driven Development". This happens when the tests have been written in advance, and we're simply completing our functions to match the specifications that had been originally defined.

Now, we'll work in reverse.

You can inspect and compare the other *.spec.js files to understand how suites, tests and assertions are made with Jest.

You're given a multiply function inside of the calculate.js file. It is already complete, and requires no work from you side.

However, there are no unit tests for this function as of yet.

Create a file named multiply.spec.js. In this file you'll create unit tests for the multiply function.

At the top of multiply.spec.js, you should import the multiply function that is exported by calculator.js. You can simply copy and paste the following line.

const { multiply } = require('./../calculator.js');

Create a test suite for the "Multiply" functionality.

describe('Multiply', () => {
  // Our tests will be added here.
});

Then, inside of this test suite, we'll be writing each of the following tests that consider the following scenarios.

  • Function is called with two positive integers. The value returned should be the result of the multiplication of both values.
  • Function is called with a negative and a positive integer. The value returned should be a negative number.
  • Function is called with any number and a number 0. The value returned should be 0 (any number multiplied by 0 equals 0).

It's up to you to decide what values the multiply function should be called with, and what values are expected as a result.

Follow the same naming pattern for tests that you find in the other test files. You can also consult the jest documentation, although you shouldn't need to.

Iteration 9 - Committing the solution

You have solved all of the prior iterations. All of the tests are passing locally.

Let's commit our work, and push it to GitHub.