An Intro Test-Driven Development and Jest

Ben Hessel
4 min readAug 4, 2022

--

When I started my time at Flatiron School, a lot of the coding we did had tests for us to pass. What I didn’t know on at that time (the very first days of learning basic methods like .forEach and .map ), was that I was learning though test-driven development (TDD).

Test-driven development is basically a method for building applications by writing (failing) tests first, and then building the application by making each test pass.

To me, this feels sort of like a video game where you have levels that need to be passed.

Your first test is your first “level,” and when you beat the boss (err… pass the test), you move on to the next level!

The original boss

For some this may make building more fun, but in general, it puts you in the mindset of feeling that the tests are a part of the building process, not just something you “have to do” after you’ve already written your code and (presumably) tested it in the browser along the way.

When we build a React app and use create-react-app , it comes with React Testing Library, which recommends also using Jest — a popular test-runner for JavaScript.

Jest is responsible for finding tests, running tests, and determining each test’s success.

In Jest, assertions are what determines if a pass tests or fails.

Assertions start with the expect function.

Second, there is an argument (in the example above this is colorButton , which was be defined on the line prior).

The argument is what the Jest tests analyze to see if it performs the way we expect.

Lastly, there is a matcher, which is also a type of assertion, and is a function used with expect .

In this case, I’m using the matcher .toBe() .

(Here’s a bunch more: https://jestjs.io/docs/expect)

Sometimes a matcher will have an argument, but not always.

So how do we write a test in Jest?

First, we have a global test method, which takes in two arguments — a string which describes what the test is, and a function that is run by Jest to determine if the test passes or fails.

We also need to render(<App />) (an import from React Testing Library).

The string directly inside test() describes what the test is, in plain English

If an assertion (e.g. expect(colorButton)... ) fails, Jest will throw us an error.

If there’s no error, you get bright green happy letters saying you’ve passed!

Perfect 👌🏻

Now, back to how to write tests…

Screen is an object also imported from React Testing Library which provides methods for querying the rendered elements.

Since we often need our tests to scan through the entire document, screen gives us an easy way to query the entire document.body .

We’ve covered expect(), but in the example above you’ll also see our matcher — .getByRole() .

This works for most tests, but there are additional types of queries as well.

Within .getByRole() , we first have to state what the role is.

Here you can check the MDN docs for all different types of roles that can be accepted (we obviously are using the first one — button).

Most often we’ll use the name option in this scenario, and this can accept a plain string as shown on the following line:

W3 also has a great resource for role definitions.

So taking a step back and looking at this entire function again…

We’re testing the button to make sure it has the correct initial color.

We render App.

We find the button who’s “name” (this is really the inner text, shown below) is “Change to blue” because in this case red should be our initial color, and we store this in a variable called colorButton .

We tell the test to expect our button (colorButton ) to have a background color of red (because again we’re testing the initial color in this test)…

…and that’s it!

Similar to running npm start to boot up localhost, we can run npm test in our terminal to run our Jest tests.

from package.json

--

--

Ben Hessel

Aspiring Software Engineer, Student at the Flatiron School