shallowly
Version:
Shallowly: Modern shallow renderer for React 18+. Enzyme-compatible API, 2x faster, with TypeScript support.
263 lines (189 loc) • 8.45 kB
Markdown
# Shallowly 🏝️ - The Modern Unit Testing Tool for React
---
[](https://www.npmjs.com/package/shallowly)
[](https://bundlephobia.com/package/shallowly)
[](https://github.com/bad4iz/shallowly/actions)
<!-- Option 4: Detailed metrics -->
[](https://codecov.io/gh/bad4iz/shallowly)
[](https://codecov.io/gh/bad4iz/shallowly)
[](https://codecov.io/gh/bad4iz/shallowly)
<!-- Code Coverage Badges -->
[](https://codecov.io/gh/bad4iz/shallowly)
<!-- Для ветки master с токеном -->
[](https://codecov.io/gh/bad4iz/shallowly)
---
## 📚 Documentation
- [English Documentation](/docs/index.md)
- [Документация на русском](/docs/index.ru.md)
- [React Architecture Guide](/docs/react-architecture.md)
- [Руководство по архитектуре React](/docs/react-architecture-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
> **Architecture & Testing**: If you think unit tests are time-consuming and expensive, take a look at our [recommended React architecture](./docs/react-architecture.md). While tests should never dictate architecture, this approach makes your code cleaner, more readable, and extensible - with unit test coverage becoming a natural byproduct. The cleaner your code, the faster and easier unit testing becomes.
## 🧪 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()`, `.textInline()`, and `.textWithPropsInline()`
- 📦 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()` / `.textWithPropsInline()` reveal structure with props, `.textInline()` gives compact text output
- ✔ 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());
console.log(wrapper.textWithPropsInline());
console.log(wrapper.textInline());
// Outputs:
// <DataFetching isLoading={true}>
// <Spinner />
// </DataFetching>
// <DataFetching isLoading={true}><Spinner /></DataFetching>
// <DataFetching><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