What is the difference between shallow and full rendering?

When it comes to testing React components, it's critical to select the approach that best fits your needs. Shallow rendering and full rendering are two popular approaches for testing React components. In this Answer, we will look at the distinctions between these two methods.

Shallow rendering

Shallow rendering is a testing technique that renders only the currently tested component, excluding its descendant components. This method allows you to isolate the component being tested and concentrate entirely on its behavior and output. Since it avoids rendering the full component tree, shallow rendering is a lightweight and efficient way to execute component testing.

Example

We will create a sample project to demonstrate the process step by step.

Setting up the project

After creating a new React project using Create React App, install the necessary dependencies. For this example project, you will need the following dependencies.

npm install react-test-renderer/shallow

Writing the test

import React from 'react';
import Subcomponent from './Subcomponent';
function MyComponent() {
return (
<div>
<span className="heading">Title</span>
<Subcomponent foo="bar" />
</div>
);
}
export default MyComponent;
import React from 'react';
function Subcomponent({ foo }) {
return <div>{foo}</div>;
}
export default Subcomponent;
import React from 'react';
import ShallowRenderer from 'react-test-renderer/shallow';
import MyComponent from './App.js';
import Subcomponent from './Subcomponent';
it('renders MyComponent correctly', () => {
const renderer = new ShallowRenderer();
renderer.render(<MyComponent />);
const result = renderer.getRenderOutput();
expect(result.type).toBe('div');
expect(result.props.children).toEqual([
<span className="heading">Title</span>,
<Subcomponent foo="bar" />
]);
});
  • Line 6: We define a test case using the it function provided by the testing framework (e.g., Jest). The test case verifies that the MyComponent renders correctly.

  • Line 7: We create a new instance of ShallowRenderer using new ShallowRenderer().

  • Line 8: We call the render method on the ShallowRenderer instance, passing in the MyComponent component as the argument. This performs the shallow rendering of the component.

  • Line 9: We retrieve the rendered output using the getRenderOutput method of the ShallowRenderer instance and assign it to the result variable.

  • Lines 11–15: We use assertions (provided by the testing framework) to check if the rendered output matches our expectations. We verify that the result is of type <div> and that its children prop is an array with a <span> element, with the class name "heading" and a Subcomponent component with the prop foo set to "bar".

Running the tests

Run the tests using the following command.

npm test

Output

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <meta name="theme-color" content="#000000" />
    <meta
      name="description"
      content="Web site created using create-react-app"
    />
    <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
    <!--
      manifest.json provides metadata used when your web app is installed on a
      user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
    -->
    <link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
    <!--
      Notice the use of %PUBLIC_URL% in the tags above.
      It will be replaced with the URL of the `public` folder during the build.
      Only files inside the `public` folder can be referenced from the HTML.

      Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
      work correctly both with client-side routing and a non-root public URL.
      Learn how to configure a non-root public URL by running `npm run build`.
    -->
    <title>React App</title>
  </head>
  <body>
    <noscript>You need to enable JavaScript to run this app.</noscript>
    <div id="root"></div>
    <!--
      This HTML file is a template.
      If you open it directly in the browser, you will see an empty page.

      You can add webfonts, meta tags, or analytics to this file.
      The build step will place the bundled scripts into the <body> tag.

      To begin the development, run `npm start` or `yarn start`.
      To create a production bundle, use `npm run build` or `yarn build`.
    -->
  </body>
</html>

Advantages

Here are a few of the advantages of shallow rendering.

  • Faster execution: Shallow rendering focuses on the component being tested, resulting in faster test execution than full rendering.

  • Isolation: Shallow rendering allows you to isolate the component under test, making it easier to debug.

  • Simplicity: Shallow rendering provides a simpler API for testing components because it avoids the complexity of rendering the complete component tree.

Full rendering

Full rendering, also referred to as deep rendering, involves rendering the full component tree, including all child components and their descendants. This method provides a more comprehensive testing environment because it simulates the component's actual behavior in a real-world application.

Example

Let's create another sample project to explain shallow rendering in React.

Setting up the project

After creating the project, install the following dependencies.

npm install --save-dev @testing-library/react react-test-renderer

Writing the test

import React from 'react';
function Button({ onClick, children }) {
return <button onClick={onClick}>{children}</button>;
}
export default Button;
  • Lines 3–5: We create a functional React component called Button that takes two props: onClick (a function to be called when the button is clicked) and children (the content inside the button). It returns a button element with the specified onClick handler and the provided children as its content.

import React from 'react';
import { render } from '@testing-library/react';
import Button from './App';
it('renders a button with correct text', () => {
const { getByText } = render(<Button onClick={() => {}}>Click me</Button>);
expect(getByText('Click me')).toBeInTheDocument();
});
  • Lines 5–8: Defines a test case with the description "renders a button with the correct text". The it function is provided by the testing framework and is used to define individual test cases.

  • Line 6: const { getByText } = render(<Button onClick={() => {}}>Click me</Button>); uses the render function to render the Button component with the specified props. The onClick prop is set to an empty arrow function, and the text "Click me" is passed as the content of the button. The render function returns an object with various querying methods, such as getByText, which we destructure from the returned object.

  • Line 7: expect(getByText('Click me')).toBeInTheDocument(); uses the expect function to assert that the text "Click me" is present in the rendered component. The getByText function is used to find the element containing the specified text. The toBeInTheDocument matcher checks if the element is present in the document. The test will be passed if it is present, otherwise fail.

Running the tests

Run the tests using the following command.

npm test

Output

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <meta name="theme-color" content="#000000" />
    <meta
      name="description"
      content="Web site created using create-react-app"
    />
    <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
    <!--
      manifest.json provides metadata used when your web app is installed on a
      user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
    -->
    <link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
    <!--
      Notice the use of %PUBLIC_URL% in the tags above.
      It will be replaced with the URL of the `public` folder during the build.
      Only files inside the `public` folder can be referenced from the HTML.

      Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
      work correctly both with client-side routing and a non-root public URL.
      Learn how to configure a non-root public URL by running `npm run build`.
    -->
    <title>React App</title>
  </head>
  <body>
    <noscript>You need to enable JavaScript to run this app.</noscript>
    <div id="root"></div>
    <!--
      This HTML file is a template.
      If you open it directly in the browser, you will see an empty page.

      You can add webfonts, meta tags, or analytics to this file.
      The build step will place the bundled scripts into the <body> tag.

      To begin the development, run `npm start` or `yarn start`.
      To create a production bundle, use `npm run build` or `yarn build`.
    -->
  </body>
</html>

Advantages

Here are a few of the advantages of full rendering.

  • Realistic testing environment: Full rendering allows you to test the component in a more realistic context because it depicts the complete component tree and captures interactions with child components.

  • Integration testing: Full rendering is well-suited for integration testing, where you need to verify the interactions between different components.

  • Accessibility testing: Full rendering provides a comprehensive environment for testing accessibility features, allowing you to check the component's functionality under different user scenarios.

Differences

Now, let us see the main differences between the shallow rendering and full rendering.

Shallow rendering vs. full rendering

Aspect

Shallow Rendering

Full Rendering

Rendered Components

Only the current component being tested

Entire component tree and child components

Test Focus

Isolates the component under test, focusing on its behavior and output

Simulates the actual behavior of the component in a real application

Test Efficiency

Faster execution due to rendering only the current component

Slower execution as it renders the entire component tree

Component Interaction

Child components are not rendered, their behavior is not captured

Captures interactions with child components

Test Complexity

Simpler API, less complexity

More complex, requires rendering and interacting with the whole tree

Use Cases

Unit testing individual components

Integration testing, testing component interactions

Debugging

Easier to debug, isolated environment

Realistic context for debugging

Accessibility Testing

Limited in testing accessibility features

Provides a comprehensive environment for testing accessibility

Conclusion

Shallow rendering and full rendering are two distinct approaches to testing React components, each with its own advantages. Full rendering provides a more thorough testing environment that includes the entire component tree, whereas shallow rendering improves speed and simplicity by focusing on the component under test. The right technique is determined by the specific requirements of your testing scenario.

Free Resources

Copyright ©2025 Educative, Inc. All rights reserved