DEV Community πŸ‘©β€πŸ’»πŸ‘¨β€πŸ’»

DEV Community πŸ‘©β€πŸ’»πŸ‘¨β€πŸ’» is a community of 964,423 amazing developers

We're a place where coders share, stay up-to-date and grow their careers.

Create account Log in
Cover image for Writing Front-End Test with Jest
ASAP_A1
ASAP_A1

Posted on

Writing Front-End Test with Jest

What is Front-End Testing

Front End testing is a systematic way of scrutinizing your application's inner & outer workings. This action ensures all views and functionalities adequately carry out their purpose and look like what they should[talk about pixel perfection in a functional context].

There are different types of testing in front-end, among which includes Unit testing, Visual regression, Performance testing…

In this tutorial, we'll be carrying out Unit testing, which checks that the functionalities across components work as expected, and we will be making use of Jest as a tool to carry out the test.

Pre-requisite

It does not require more than having your latest node.js software installed and a working keyboard.

Testing Testing 123...

I will be using my already created vite application. See the tutorial here.
On the other hand a create-react-app solves it here;

yarn create-react-app my-first-test
Enter fullscreen mode Exit fullscreen mode

If you already have a project, you'll only have to add the react-test-renderer package in order to show us our snapshots

yarn add react-test-renderer
Enter fullscreen mode Exit fullscreen mode

Moving forward, we will be making use of babel-react and react babel will help us to transform it into the test environment hence;

yarn add --dev jest babel-jest @babel/preset-env @babel/preset-react
Enter fullscreen mode Exit fullscreen mode

After that your package.json should look like this. Mine might be more code cause, like I mentioned is an inherited[existing] project.

Json file snapshot

Create a babel.config.json file and add this;

{
  "presets": [
    [
      "@babel/preset-env",
      {
        "targets": {
          "node": "current"
        }
      }
    ],
    "@babel/preset-react"
  ]
}
Enter fullscreen mode Exit fullscreen mode

VoilΓ !

Now it's time to make our Snapshot Test...

Let's test if our reusable button component works as we want it. Our Button.js the component should be like this;

import React, { useState } from "react";

const ACTIONS = {
  CLICKED: "clicked",
  HOVERED: "hovered",
  NORMAL: "normal",
};

const PrimaryButton = ({ children, variant }) => {
  const [actions, setActions] = useState(ACTIONS.CLICKED);

  const onClick = () => {
    setActions(ACTIONS.CLICKED);
  };
  const onMouseEnter = () => {
    setActions(ACTIONS.HOVERED);
  };
  const onMouseLeave = () => {
    setActions(ACTIONS.NORMAL);
  };

  return (
    <>
      <button
        onClick={onClick}
        variant={variant || "primaryButton"}
        className={actions}
        onMouseEnter={onMouseEnter}
        onMouseLeave={onMouseLeave}
      >
        {children}
      </button>
    </>
  );
};

export default PrimaryButton;

Enter fullscreen mode Exit fullscreen mode

Supper chill, yeah?
Next, we will create a file called Labs.test.js, in this file, we'll be using our React renderer and Jest snapshot feature to interact with our components capturing the rendered snapshot as output and appending it to a new snapshot file.

import React from "react";
import renderer from "react-test-renderer";
import PrimaryButton from "./Button";

it("it triggers the follow up functions when clicked", () => {
  const component = renderer.create(
    <PrimaryButton variant={"primaryButton"}>SignIn</PrimaryButton>
  );
  let primaryButton = component.toJSON();
  expect(primaryButton).toMatchSnapshot();

  //triggering click act
  renderer.act(() => {
    primaryButton.props.onClick();
  });
  //comparing Org
  primaryButton = component.toJSON();
  expect(primaryButton).toMatchSnapshot();

  //triggering enter act
  renderer.act(() => {
    primaryButton.props.onMouseEnter();
  });
  //comparing Org
  primaryButton = component.toJSON();
  expect(primaryButton).toMatchSnapshot();

  //triggering normal act
  renderer.act(() => {
    primaryButton.props.onMouseLeave();
  });
  //comparing Org
  primaryButton = component.toJSON();
  expect(primaryButton).toMatchSnapshot();
});
Enter fullscreen mode Exit fullscreen mode

Now on your CLI run yarn test or yarn jest and expect this output;

Test result

Hence aforementioned, a file __snapshots__/Labs.test.js.snap will be created automatically and have the following snapshots.

// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`it triggers the follow up functions when clicked 1`] = `
 <button
  className="clicked"
  onClick={[Function]}
  onMouseEnter={[Function]}
  onMouseLeave={[Function]}
  variant="primaryButton"
>
  SignIn
</button>
`;

exports[`it triggers the follow up functions when clicked 2`] = `
<button
  className="clicked"
  onClick={[Function]}
  onMouseEnter={[Function]}
  onMouseLeave={[Function]}
  variant="primaryButton"
>
  SignIn
</button>
`;

exports[`it triggers the follow up functions when clicked 3`] = `
<button
  className="hovered"
  onClick={[Function]}
  onMouseEnter={[Function]}
  onMouseLeave={[Function]}
  variant="primaryButton"
>
  SignIn
</button>
`;

exports[`it triggers the follow up functions when clicked 4`] = `
<button
  className="normal"
  onClick={[Function]}
  onMouseEnter={[Function]}
  onMouseLeave={[Function]}
  variant="primaryButton"
>
  SignIn
</button>
`;

Enter fullscreen mode Exit fullscreen mode

Finally, when you eventually make a change to your component, you'll need to update the test suit to capture the changes. If not, you'll get errors thrown at you. Therefore, run yarn jest -uto resolve that.
Thank you for following up on this tutorial. If you find or think it might help someone, do not hesitate to share.
Gracias Macho!

Top comments (0)

Classic DEV Post from 2020:

js visualized

πŸš€βš™οΈ JavaScript Visualized: the JavaScript Engine

As JavaScript devs, we usually don't have to deal with compilers ourselves. However, it's definitely good to know the basics of the JavaScript engine and see how it handles our human-friendly JS code, and turns it into something machines understand! πŸ₯³

Happy coding!