UNPKG

shallowly

Version:

Shallowly: Modern shallow renderer for React 18+. Enzyme-compatible API, 2x faster, with TypeScript support.

246 lines (179 loc) โ€ข 7.09 kB
# Shallowly ๐Ÿ๏ธ - The Modern Unit Testing Tool for React --- [![npm version](https://img.shields.io/npm/v/shallowly?style=flat-square)](https://www.npmjs.com/package/shallowly) [![minzipped size](https://img.shields.io/bundlephobia/minzip/shallowly?style=flat-square)](https://bundlephobia.com/package/shallowly) [![build status](https://img.shields.io/github/actions/workflow/status/bad4iz/shallowly/tests.yml?style=flat-square)](https://github.com/bad4iz/shallowly/actions) [![coverage](https://img.shields.io/codecov/c/github/bad4iz/shallowly?style=flat-square)](https://codecov.io/gh/bad4iz/shallowly) --- ## ๐Ÿ“š Documentation - [English Documentation](/docs/index.md) - [ะ”ะพะบัƒะผะตะฝั‚ะฐั†ะธั ะฝะฐ ั€ัƒััะบะพะผ](/docs/index.ru.md) - [Development Guide](/docs/dev.md) - [ะ ัƒะบะพะฒะพะดัั‚ะฒะพ ั€ะฐะทั€ะฐะฑะพั‚ะบะธ ะฝะฐ ั€ัƒััะบะพะผ](/docs/dev.ru.md) ## ๐ŸŽฏ Key Purpose: Laser-Focused Unit Testing **"Shallowly exists for one purpose: fast, isolated unit tests of YOUR React components."** ### Why Unit Testing Matters: - ๐Ÿ” **Isolated verification** - Test components in complete isolation - โšก **Instant feedback** - Get results in milliseconds, not seconds - ๐Ÿงฉ **Precise targeting** - Verify one component at a time - ๐Ÿ›ก๏ธ **Safe refactoring** - Change implementation without breaking tests ## ๐Ÿงช Testing Philosophy > **"Don't test React or third-party libraries - only test the code YOU wrote here."** > _Shallowly's core mantra_ ### Why this matters: 1. ๐Ÿšซ **No redundant tests** - React and popular libraries are already well-tested by their maintainers 2. ๐Ÿ’ก **Focus on business logic** - Verify only your unique functionality 3. โšก **Blazing fast** - Skip unnecessary rendering of entire component trees 4. ๐ŸŽฏ **Precise targeting** - Test components in complete isolation 5. ๐Ÿ”’ **Future-proof** - Your tests won't break when dependencies update > "Good tests don't check how React works - they check how YOUR application works with React." ### What this means in practice: โœ… DO test: - Your component's output - Your business logic - Your custom hooks - Your state management โŒ DON'T test: - React's internal behavior - Third-party component rendering - Library implementation details ## The Modern Shallow Renderer for React 18+ Testing **The modern Enzyme alternative** for fast unit testing with: - โœ… Full React 18+ support (Hooks, Context, Suspense) - ๐Ÿš€ Enzyme ๐Ÿ”š๐Ÿ’€ It is no longer supported or operational. - โšก **7x faster** than React Testing Library - ๐Ÿ” Built-in debug with `.textWithProps()` - ๐Ÿ“ฆ 5KB size (3x smaller than Enzyme) ๐Ÿ”š๐Ÿ’€ It is no longer supported or operational. - ๐Ÿ›  Familiar API - easy migration from Enzyme ## ๐Ÿš€ Why Shallowly? Enzyme is deprecated, and React Testing Library doesn't support shallow rendering. Shallowly solves this with: - โœ” Future-proof - Full support for React 18+ (Hooks, Context, Suspense) - โœ” Blazing fast - 2x quicker render cycles than Enzyme (benchmarks) - โœ” Familiar API - Enzyme-like syntax for painless migration - โœ” Debug-friendly - .textWithProps() reveals your component structure - โœ” Tiny footprint - 5KB (gzipped), zero dependencies ```bash npm install shallowly # or yarn add shallowly ``` ## โœจ Key Features ### 1. React 18+ Ready Test modern features without workarounds: ```jsx shallow( <Suspense fallback={<Loader />}> <AsyncComponent /> </Suspense>, ); ``` ### 2. Enzyme Compatibility Layer ```diff - import { shallow } from 'enzyme'; + import { shallow } from 'shallowly'; // Same API! ``` ### 3. Visual Debugging ```jsx console.log(wrapper.textWithProps()); // Outputs: // <DataFetching isLoading={true}> // <Spinner /> // </DataFetching> ``` ### 4. TypeScript Native ```tsx const wrapper = shallow<Props>(<User id={123} />); wrapper.prop("id"); // Type-safe: number ``` ## ๐Ÿ“ฆ Quick Start ### Install: ```bash npm install shallowly --save-dev ``` ### Write tests: ```jsx import { shallow } from "shallowly"; import vi from "vitest"; const MyComponent = ({ name, age, onClick }) => ( <div className="container"> <h1>Hello {name}</h1> <p>You are {age} years old</p> <button onClick={onClick}>Click me</button> </div> ); describe('๐Ÿ› MyComponent', () => { it('๐Ÿงช default', () => { expect.hasAssertions(); //โ˜ฃ๏ธ Arrange (ะฒััะบะธะต ะผะพะบะธ) const onClickSpy = vi.fn(); //๐Ÿ”ฅ Act const wrapper = shallow( <MyComponent name="John" age={30} onClick={onClickSpy} />, ); //โ“ Assert expect(wrapper.text()).toMatchSnapshot(); }); it('๐Ÿงช button prop onClick', () => { expect.hasAssertions(); //โ˜ฃ๏ธ Arrange (ะฒััะบะธะต ะผะพะบะธ) const onClickSpy = vi.fn(); //๐Ÿ”ฅ Act const wrapper = shallow( <MyComponent name="John" age={30} onClick={onClickSpy} />, ); //โ“ Assert expect(wrapper.find('button').prop('onClick')).toBe(onClickSpy); }); }); ``` ### Snapshot Testing ```snap // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html exports[`๐Ÿ› MyComponent > ๐Ÿงช default 1`] = ` "<div> <h1> Hello John </h1> <p> You are 30 years old </p> <button> Click me </button> </div>" `; ``` ## โšก Performance Comparison | Operation | Shallowly ๐Ÿš€ | Enzyme | React Testing Library | | ------------------------ | -----------: |-----------------------------------------------:| --------------------: | | **Basic component** | 12ms โšก | ๐Ÿ”š๐Ÿ’€ It is no longer supported or operational. | 85ms (7.1x slower) | | **100 components** | 650ms โšก | ๐Ÿ”š๐Ÿ’€ It is no longer supported or operational. | 4500ms (6.9x slower) | | **Hook-heavy component** | 18ms โšก | ๐Ÿ”š๐Ÿ’€ It is no longer supported or operational. | 210ms | | **Tree traversal** | 8ms โšก | ๐Ÿ”š๐Ÿ’€ It is no longer supported or operational. | 150ms | **Key takeaways:** - ๐ŸŽ๏ธ Enzyme ๐Ÿ”š๐Ÿ’€ It is no longer supported or operational. - โšก **7x faster** than React Testing Library - ๐Ÿง  **40% less memory usage** compared to Enzyme - ๐ŸŒณ **Zero DOM** - pure React reconciliation ## ๐Ÿ›  Perfect For - โœ… Unit testing React components - โœ… Migrating from Enzyme - โœ… Testing complex hooks/context flows - โœ… CI pipelines (fast execution) ## ๐Ÿšซ What Shallowly Is NOT For: - โŒ End-to-end testing (use Cypress/Playwright) - โŒ Full integration testing (use RTL) - โŒ Visual regression testing (use Storybook/Chromatic) ## ๐Ÿ“Š Unit Testing Pyramid ```terminal pie title Test Distribution "Unit (Shallowly)" : 70 "Integration" : 20 "E2E" : 10 ``` ๐Ÿ“š [English Documentation](/docs/index.md) | ๐Ÿ‡ท๐Ÿ‡บ [ะ”ะพะบัƒะผะตะฝั‚ะฐั†ะธั ะฝะฐ ั€ัƒััะบะพะผ](/docs/index.ru.md) | ๐Ÿž [Report Issues](https://github.com/bad4iz/shallowly/issues) "Saved us 300+ lines of test boilerplate!" - @bad4iz