# WASM Internals 2: Unit testing

## Questions to be answered in this chapter

* **How** can webassembly modules be tested?
* Which **frameworks** exist to test webassembly?
* Is there any **interoperability** with the testing frameworks already built for **Javascript**?

## Introduction

{% embed url="<https://github.com/antferdom/wasm_playground>" %}
Github with the wasm source code
{% endembed %}

As the purpose of this chapter is to illustrate how to **test** webassembly code, the first part addresses which dependencies need to be added. These new dependencies won't be anything else than the chosen **javascript test framework**. In this chapter **jest** will be placed as the best candidate.

Once all the configuration is completed, it's the moment to start creating the **unit tests**. For the sake of simplicity and cohesion with the previous part, the testing will target the **square** function.

**NOTE:** This second part uses the code already introduced in the first chapter, as it will be necessary for the purposes of the explanation.

## Changes added to package.json

The **type** must indicate that it's a **module**. Thus it can recognize **ES6** modules. If needed, additional information about using ES6 Javascript modules can be found at the end of the chapter. Once this specification is done, the desired module can be executed using **Node.js**.

**File:** package.json

```json
.. ..  
  "type": "module", ...
```

Now, the **unit tests** can be created and run using any common javascript testing framework, usually used for **Node.js** ordinary modules without any webassembly. To do so, a javascript testing framework will be needed. For the sake of robustness and simplicity, **jest** (powered by Facebook) is the alternative chosen. But take into account that **any** other framework would be valid. In an industrial ecosystem this decision would be done according to the **characteristics** of the company.

## Installing jest as the javascript testing framework

The procedure looks as follows:

Install Jest using **yarn**:

```shell
yarn add --dev jest
```

Or **npm**:

```shell
npm install --save-dev jest
```

In both cases, the **flag** `dev-dependecy`. It's purpose is to act as a dev dependency rather than a production dependency.

Note: Jest documentation uses **yarn commands**, but npm will also work. You can compare yarn and npm commands in the [yarn docs, here](https://classic.yarnpkg.com/en/docs/migrating-from-npm#toc-cli-commands-comparison).

Then add jest to the **package.json**. More precisely to it's **test** variable. An example of the final form of the file would be:

**File:** package.json

```json
.. ..  
"scripts": {
    "test": "jest"
  }, ...
```

## Creating a simple webassembly unit test

All the tests created for this project will be under the **test** directory. In order to let jest address the **location** of the test created, they need to be **named** with the following **pattern**:

```
<undetermined_name>.test.js
```

In this case, a file named **math.test.js** is created to contain the unit tests.

In the creation of the unit case appears a lot of similarities with the code inhabiting **index.js**. The main differences are:

1. **Import statements**: Because jest struggles dealing with **ES6** modules, the **old** common import statements, from **ES5** and **below**, are going to be used.

```javascript
const fs = require('fs');
```

**NOTE**: There is a **beta** support for **ES6** modules going on inside jest. But here those considerations are omited.

1. **Load the desired webassembly module**: Before even attempting to test the targeted webassembly module, it needs to be loaded. To do this, the function **beforeAll** from jest will be used. It's going to be declared as an **async** function.

```javascript
beforeAll(async () => {
    const math_wasm = fs.readFileSync('./public/math.wasm');
    math = await WebAssembly.instantiate(new Uint8Array(math_wasm))
                    .then(result => result.instance.exports);
})
```

**NOTE**: The math variable is declared as **global**, so it can be accessed **anywhere** in the code and its **scope** is not limited to just being accessed inside **beforeAll**.

The final **assertion** using the jest syntax and calling mechanics:

*e.g:*

```javascript
test('Square operation with 2 as param', () => expect(math.square(2)).toBe(4) );
```

It's expected that given the **square** function and **2** as its **input** argument, the computed **output** would be **4.**

## Running the tests

To run the **entire** set of test for the given project:

```
npm run test
```

**example output:**

```shell
> wasm_playground_1@1.0.0 test
> jest

 PASS  test/math.test.js
  ✓ Square operation with 2 as param (1 ms)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        0.148 s
Ran all test suites.
```

## References

{% embed url="<https://www.youtube.com/channel/UCncVoOXAma1zJUNTJGL6Ncw>" %}

1. [How to use an ES6 import in Node.js? (GeeksforGeeks)](https://www.geeksforgeeks.org/how-to-use-an-es6-import-in-node-js/)
2. [Jest](https://jestjs.io)
3. [Naming conventions in the Javascript testing ecoystem](https://stackoverflow.com/questions/49632743/what-is-the-convention-for-javascript-test-files)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://a-j.gitbook.io/wasm-experimentation/wasm-internals-2-unit-testing.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
