CS 312 - Software Development

CS 312 - Practical Five

Goals

  • Implement BDD tests for a React application based on Cucumber scenario

Prerequisites

  1. Click through to the GitHub classroom assignment to create your private repository. Then clone that newly created repository to your local computer as you have done previously.

  2. Install the package dependencies by running npm install inside the root directory of the newly cloned repository.

You previously used Jest for unit testing JS code and Jest and the React Testing Library in combination to unit test React components. Today we will focus on behavioral testing as part of Behavior-Driven Design (BDD).

Scenario testing with the Testing Library

In class we developed a Cucumber-style test scenario for the toggling between the summary and detail views. Using the Testing Library, you can implement similar tests, albeit a little more closely tied to the React implementation. You could rewrite our scenario as:

Given the FilmContainer is rendered
And the film overview can't be seen
When I click on the film's title
Then I expect the overview to exist
And I expect the poster to exist
When I click on the film's title
Then I expect the film's overview not to exist

Today we will implement the above test scenario in FilmContainer.test.js.

I have given you an initial test:

test('Initially renders summary view', () => {
  render(<FilmContainer {...film} setRatingFor={jest.fn} />);
  expect(screen.queryByText(film.title)).toBeInTheDocument();
  expect(screen.queryByText(film.overview)).not.toBeInTheDocument();
});

This is, in essence, the precondition for the scenario. When we render the component, we can see the title, but we can't see the overview -- thus we are looking at the summary, not the detail view.

The matcher toBeInTheDocument comes from the jest-dom library, which includes a number of helpful matchers for querying aspects of the DOM. You can use these same lines as the beginning of your test.

Note that we use queryBy because one of those elements will not be present. We could have used getBy for the title, since it should be present.

Now, our scenario requires the title to be clicked.

Recall that we can click on elements with fireEvent.click(element), where element is a DOM element. You already have a query for finding the film's title in the DOM.

After the click, we expect the summary to be present, so test for it.

We also expect to see the poster image. We can search for the image using getByRole. The role for images is 'img'. We want to check two things about the poster: is it visible, and does it have the path we expect. As such, rather than plugging the query directly into an expect as we have been, save the result in a variable called poster.

Now, check if the the poster is visible (toBeVisible()). Then, check the poster's src. You can get the src with poster.src. A straightforward toBe matcher is fine for the string match (careful, make sure you know what the full src should be...)

Finish up with the second when: click the title again and make sure that everything is back to the summary view again.

Finishing Up

  1. Add and commit your changes and push those commit(s) to GitHub.
  2. Submit your repository to Gradescope