Snapshot Testing with Jest: Ensuring UI Consistency
Snapshot testing is a powerful technique to detect unintended changes in your UI components. Instead of manually asserting every property and state of a component's output, you "snapshot" its rendered output and compare it against a previously saved "golden" snapshot in subsequent test runs. This challenge will guide you through implementing and utilizing snapshot testing in Jest for a simple React component.
Problem Description
Your task is to create snapshot tests for a basic UserProfileCard React component using Jest. This component displays a user's name, email, and avatar. You need to:
- Create a
UserProfileCardReact component (or use a provided basic structure if preferred). - Configure Jest to run snapshot tests for this component.
- Write Jest tests that capture and compare snapshots of the
UserProfileCardcomponent with different sets of props. - Understand how to update snapshots when intentional changes are made to the component.
The goal is to ensure that any future modifications to the UserProfileCard component do not introduce visual regressions or unexpected changes in its structure.
Examples
Let's assume a UserProfileCard component exists.
Example 1: Basic User Profile
Input Props:
{
name: "Alice Wonderland",
email: "alice@example.com",
avatarUrl: "https://example.com/avatars/alice.png"
}
Expected Snapshot Output (in a __snapshots__ directory, e.g., `UserProfileCard.test.tsx.snap`):
exports[`UserProfileCard renders correctly 1`] = \`
<div className="user-profile-card">
<img src="https://example.com/avatars/alice.png" alt="Alice Wonderland avatar" className="avatar" />
<h2>Alice Wonderland</h2>
<p>alice@example.com</p>
</div>
\`;
Explanation:
The first time the test runs, Jest will generate a .snap file containing the HTML structure rendered by UserProfileCard with the given props. This becomes the "golden" snapshot.
Example 2: User Profile with Missing Avatar
Input Props:
{
name: "Bob The Builder",
email: "bob@example.com"
}
Expected Snapshot Output:
exports[`UserProfileCard renders without avatar 1`] = \`
<div className="user-profile-card">
<img src="/default-avatar.png" alt="Default avatar" className="avatar" />
<h2>Bob The Builder</h2>
<p>bob@example.com</p>
</div>
\`;
Explanation:
If the avatarUrl prop is missing, the component should render a default avatar. The snapshot test will capture this behavior.
Example 3: User Profile with Long Name
Input Props:
{
name: "Charlie E. Chapplin-Senior-Jr.",
email: "charlie.jr@example.com",
avatarUrl: "https://example.com/avatars/charlie.png"
}
Expected Snapshot Output:
exports[`UserProfileCard handles long names 1`] = \`
<div className="user-profile-card">
<img src="https://example.com/avatars/charlie.png" alt="Charlie E. Chapplin-Senior-Jr. avatar" className="avatar" />
<h2>Charlie E. Chapplin-Senior-Jr.</h2>
<p>charlie.jr@example.com</p>
</div>
\`;
Explanation: This tests how the component renders with potentially longer text in the name field.
Constraints
- Your solution should be written in TypeScript.
- You must use Jest as your testing framework.
- You should leverage
@testing-library/reactfor rendering React components in tests. - The
UserProfileCardcomponent should be a functional React component. - The generated snapshot files should reside in a
__snapshots__directory adjacent to your test files.
Notes
- To initialize a new React project with TypeScript and Jest, consider using tools like Create React App (with the
--template typescriptflag) or Vite. - You will need to install the necessary testing libraries:
jest,@types/jest,ts-jest,react,react-dom,@testing-library/react,@testing-library/jest-dom. - Remember to configure your
jest.config.js(orjest.config.ts) for TypeScript support (e.g., usingts-jest). - The first time you run your snapshot tests, Jest will create the
.snapfiles. Subsequent runs will compare the current output to these files. If they differ, the test will fail, indicating a potential regression. - To update existing snapshots after making intentional changes, run Jest with the
--updateSnapshotflag (e.g.,jest --updateSnapshot).