# Learn testing in JavaScript

The concept of testing code is often introduced with complex libraries. This hides the core of testing: writing some code that runs your other code and tells you if it's wrong. This workshop introduces the concept by slowly building up a useful function that helps you test your code.

### Setup

1. Download the starter files
2. Open `starter-files/workshop.html` in your editor

There should be a function that squares a number (multiplies it by itself). It's used like this:

```js
const result = square(2);
console.log(result); // 4
```

Right now we only have one option for checking this works. We have to call the function, log the result, then check that result (with a calculator for bigger numbers).

If you want to check it works for lots of different numbers you'll be doing a bunch of manual work. You'll have to repeat this work every time the code changes (to make sure you didn't break it). It would be helpful to automate this process.

### Begin to automate

Since you know how to code you can begin to automate this! Write some JavaScript that calls the `square` function (like above), then checks that the result is what you expect. It should log a useful message to the console using `console.error("my message")` if the result is wrong.

If your test passes change your expected value so that it's definitely wrong. Can you see the failure in your browser console?

### Make it reusable

This is better than manually checking, but not much. We have to write all the same logic for checking whether the values are the same and logging every time. It would be a lot of copy/pasting to write 20 tests.

#### `equal`

Most tests check whether two things are equal. It's helpful if we extract that logic into a reusable function.

Write a function called `equal` that takes two arguments and checks if they're the same. If they are it should log the success with `console.info`. If they aren't it should log the failure with `console.error`.

Use this `equal` function to refactor your test above, then write another one to check that `square(3.5)` is correct.

If your test is passing change your expected value so that it's definitely wrong. Can you see the error in your browser console?

#### `notequal`

It's sometimes useful to be able to check whether two things are *not* equal

Write a `notEqual` function. It should be similar to `equal`, but log a failure when its two arguments *are* the same.

Write a test that checks `square(3)` does not return 10.

### Separating tests

Right now our tests are all jumbled together. This means they share the same scope, so we can't reuse variable names. It's also hard to distinguish them in the console. It would be nice if each test had a descriptive name.

We could divide our tests up using functions, like this:

```js
test("Correctly squares integers", () => {
  const result = square(2);
  const expected = 4;
  equal(result, expected);
});

test("Correctly squares integers", () => {
  const result = square(3.5);
  const expected = 12.25;
  equal(result, expected);
});
```

We call a `test` function with a descriptive name, and pass a callback function containing our test code.

Write a function called `test` that takes two arguments: a `name` and a `testFunction`. It should use [`console.group`](https://developer.mozilla.org/en-US/docs/Web/API/Console/group) to log a group labelled with the `name`. You'll need [`console.groupEnd`](https://developer.mozilla.org/en-US/docs/Web/API/Console/groupEnd) to close the group at the end.

It should call the `testFunction` callback argument so that the actual test is run.

![](/files/m2lXiaV0nUsd6KgehEm1)

### Custom messages

For more complex assertions it's nice to be able to write a custom message specific to that test.

Amend your `equal` and `notEqual` functions so that they take a third optional `message` argument. Your `console.info`/`console.error` should log this message. If there is no `message` passed in then default to the message you were using before.

### That's it

Congratulations, you've built a testing library from scratch!

We are missing some stuff (support for testing async code, a summary of total passing/failing tests), but we can get pretty far with just this.


---

# 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://founders-and-coders.gitbook.io/coursebook/src/workshops/learn-testing/index.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.
