Introduzione
Lo sviluppo di componenti web moderni nel frontend si basa su pratiche di riuso, modularità e affidabilità del codice. Per raggiungere questi obiettivi è fondamentale disporre di strumenti che semplifichino il testing sia visivo che funzionale. In questo articolo vedremo come integrare Storybook e Jest per costruire un flusso di lavoro completo: da un lato la documentazione interattiva dei componenti, dall’altro test unitari e snapshot per convalidarne il comportamento.
Installazione di Storybook
Storybook è un ambiente di sviluppo che permette di visualizzare e interagire con i componenti UI in isolamento. Questo approccio riduce la complessità e aiuta a individuare bug in modo più rapido.
- Esegui l’inizializzazione del progetto con
npx create-react-app
o un framework a scelta. - Aggiungi Storybook con:
npx storybook init
Questo comando configurerà automaticamente alcuni script di base. Dopo l’installazione, potrai avviare l’ambiente locale con:
npm run storybook
Si aprirà una dashboard dove potrai navigare tra i tuoi componenti.
Configurazione di Jest
Jest è uno strumento versatile per test unitari in ambiente JavaScript. Integrare Jest con Storybook consente di garantire che i componenti non solo appaiano correttamente, ma funzionino come previsto.
Per configurarlo:
npm install --save-dev jest @testing-library/react @testing-library/jest-dom
All’interno del file package.json
aggiungi lo script:
{
"scripts": {
"test": "jest"
}
}
Jest potrà così eseguire i test definiti nei file .test.js
o .spec.js
.
Scrivere test per i componenti
Supponiamo di avere un componente Button
. Ecco come potremmo definirlo:
// Button.js
export function Button({ label, onClick }) {
return <button onClick={onClick}>{label}</button>;
}
Per testarlo con Jest e Testing Library:
// Button.test.js
import { render, screen, fireEvent } from '@testing-library/react';
import { Button } from './Button';
describe('Button component', () => {
it('deve renderizzare il label', () => {
render(<Button label="Clicca" onClick={() => {}} />);
expect(screen.getByText('Clicca')).toBeInTheDocument();
});
it('deve richiamare onClick quando cliccato', () => {
const handler = jest.fn();
render(<Button label="Clicca" onClick={handler} />);
fireEvent.click(screen.getByText('Clicca'));
expect(handler).toHaveBeenCalledTimes(1);
});
});
In questo modo abbiamo validato sia il rendering che la funzionalità del componente.
Ottimizzazione del flusso di lavoro
Usare Storybook e Jest in combinazione significa poter documentare i componenti nelle storie e allo stesso tempo assicurarsi che ogni comportamento sia testato. Un consiglio pratico è mappare ogni storia a un test, riducendo la probabilità di divergenze tra documentazione e implementazione.
Ad esempio, se hai una storia chiamata “Primary” per un pulsante, crea un test associato nell’omonimo file test. Questo garantisce una corrispondenza diretta tra “design documentato” e “test validato”.
Esempi pratici
1. Storybook Stories
// Button.stories.js
import { Button } from './Button';
export default {
title: 'Components/Button',
component: Button,
};
export const Primary = () => <Button label="Salva" onClick={() => alert('cliccato!')} />;
export const Disabled = () => <Button label="Disabilitato" onClick={() => {}} disabled />;
2. Snapshot Testing
// Button.snapshot.test.js
import renderer from 'react-test-renderer';
import { Button } from './Button';
test('snapshot del Button', () => {
const tree = renderer.create(<Button label="Snapshot" onClick={() => {}} />).toJSON();
expect(tree).toMatchSnapshot();
});
3. Styling CSS e test su classi
/* button.css */
.button-primary {
background-color: #0070f3;
color: #fff;
padding: 0.5rem 1rem;
border-radius: 4px;
}
.button-disabled {
opacity: 0.5;
cursor: not-allowed;
}
// ButtonWithClass.js
import './button.css';
export function ButtonWithClass({ label, disabled }) {
const className = disabled ? 'button-disabled' : 'button-primary';
return <button className={className} disabled={disabled}>{label}</button>;
}
// ButtonWithClass.test.js
import { render, screen } from '@testing-library/react';
import { ButtonWithClass } from './ButtonWithClass';
test('applica classe disabled corretta', () => {
render(<ButtonWithClass label="Disabilitato" disabled />);
expect(screen.getByText('Disabilitato')).toHaveClass('button-disabled');
});
Strategie di testing avanzate
Oltre ai test unitari tradizionali, è utile applicare:
- Testing delle interazioni complesse: come l’apertura di modali o dropdown.
- Mock API: simulare risposte asincrone con Jest per valutare l’integrazione dei componenti.
- Visual Regression Testing: utilizzare plugin come Chromatic per Storybook, che confronta screenshot tra versioni diverse dei componenti.
Ricorda: un buon suite di test non deve solo controllare i casi base, ma prevenire regressioni in scenari reali e complessi.
Conclusione
L’uso congiunto di Storybook e Jest offre ai frontend developer un ecosistema completo per lo sviluppo e la convalida dei componenti. Da un lato la documentazione visiva e interattiva per il team, dall’altro l’affidabilità delle unit test e snapshot automatizzati. Investire tempo nell’automazione del testing significa ottenere maggiore stabilità, ridurre bug in produzione e velocizzare il ciclo di sviluppo.