Skip to content

Commit

Permalink
Content(nodejs loaders) (#350)
Browse files Browse the repository at this point in the history
* WIP

* WIP

* WIP

* update with feedback

* update
  • Loading branch information
AugustinMauroy authored Dec 12, 2024
1 parent c8344d2 commit 2641754
Show file tree
Hide file tree
Showing 2 changed files with 340 additions and 0 deletions.
170 changes: 170 additions & 0 deletions content/blog/how-to-test-react-app-with-node-test-runner.en.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
---
title: How to test a React app with Node Test Runner
description: Drastically simplify and speed up testing your React app by switching to Node Test Runner.
date: 2024-12-10
authors: AugustinMauroy
---

## Introduction

Testing is a crucial part of software development, ensuring that your application behaves as expected. With the [Node.js Test Runner](https://nodejs.org/en/learn/test-runner/introduction), you can seamlessly integrate testing into your [React](https://react.dev) application. This guide will walk you through the process of setting up and running tests for a React app using the Node.js Test Runner.

> I really recommend you to read the [Node.js Test Runner guides](https://nodejs.org/en/learn/test-runner/introduction) to understand how node.js test runner works.
> This guide assumes you have a basic understanding of React and testing.
## Installing the Dependencies

First, you need to install the necessary dependencies. In addition to your React app dependencies, you will need the following:

```bash
npm install --save-dev @testing-library/react @testing-library/dom jsdom global-jsdom
```

> **Note**: The rest of the dependencies we will use come from Node.js.
## Writing the Component to Be Tested

Let's create a simple React component that we will test. This component will be a counter that increments a value when a button is clicked.

```tsx fileName="src/components/Counter/index.tsx"
'use client';
import { useState } from 'react';
import styles from './index.module.css';
import type { FC } from 'react';

const Counter: FC = () => {
const [count, setCount] = useState(0);

return (
<div className={styles.container}>
<p className={styles.count}>{count}</p>
<button onClick={() => setCount(count + 1)} className={styles.button}>
Increment
</button>
</div>
);
};

export default Counter;
```

<details>
<summary>`index.module.css`</summary>

```css fileName="src/components/Counter/index.module.css"
.container {
@apply flex flex-col items-center justify-center;

.count {
@apply text-4xl;
}

.button {
@apply px-4 py-2 bg-blue-500 text-white rounded-md;
}
}
```
</details>

## Registering Node.js Loaders

To handle TypeScript and CSS modules, you need to register the appropriate loaders. Create a file named `node-hooks/react-test.js` and add the following code:

> To understand what is a loader, check out [this post](/blog/post/how-to-use-nodejs-loader).
You'll need to register the loaders for TypeScript and CSS modules:

First let's install the loaders:

```bash
npm add -D @nodejs-loaders/tsx @nodejs-loaders/css-module
```

Then, create the registration file:

```mjs fileName="node-hooks/react-test.js"
import { register } from 'node:module';
import { pathToFileURL } from 'node:url';
import jsdom from 'global-jsdom';

// Register the loaders
register('@nodejs-loaders/tsx', pathToFileURL('./'));
register('@nodejs-loaders/css-module', pathToFileURL('./'));

jsdom(undefined, {
// ⚠️ Failing to specify this will likely lead to many 🤬
url: 'https://test.example.com',
});
```

## Writing the Test

Now, let's write a test for the `Counter` component. Create a file named `index.test.tsx` in the same directory as your component:

```tsx fileName="src/components/Counter/index.test.tsx"
import assert from 'node:assert/strict';
import { describe, it } from 'node:test';
import { render, fireEvent, screen } from '@testing-library/react';
import Counter from './index.ts'; // ⚠️ We need to import the file with the .ts extension

describe('Counter', () => {
it('should increment the count when the button is clicked', () => {
const { unmount } = render(<Counter />);

const button = screen.getByRole('button', { name: /increment/i });
const count = screen.getByText('0');

assert.strictEqual(count.textContent, '0');

fireEvent.click(button);

assert.strictEqual(count.textContent, '1');

// ⚠️ It's a good idea to unmount the component to prevent it spilling over into the DOM of other tests
unmount();
});
});
```

### Structure of a Test File

A typical test file structure includes:

1. **Imports**: Import the necessary modules and components.
2. **Test Suite**: Define a test suite using `describe`.
3. **Test Case**: Define individual test cases using `it`.
4. **Render the Component**: Render the component to be tested.
5. **Perform Actions**: Simulate user interactions or other actions.
6. **Assertions**: Make assertions to verify the expected behavior.
7. **Unmount the Component**: Clean up by unmounting the component.

## Running the Test

To run the test, use the following command:

```bash
node --test --import="./node-hooks/typescript.js" --import="./node-hooks/react.js" **/*.test.tsx
```

You can also add a script to your `package.json` to simplify running the tests:

```json fileName="package.json"
{
"scripts": {
"test:unit": "node --test --import=\"./node-hooks/typescript.js\" --import=\"./node-hooks/react.js\" **/*.test.tsx",
"test:watch": "node --run test:unit --watch"
}
}
```

> **Note**: You can add more patterns to the glob pattern to test more files. For example, `**/*.test.ts` to test all TypeScript files.
And then to call the script you can use `--run`:

```bash
node --run test:unit # or node --run test:watch
```

## Conclusion

Testing your React app with the Node.js Test Runner is a straightforward process. By following the steps outlined in this guide, you can ensure that your components behave as expected. Happy testing!
170 changes: 170 additions & 0 deletions content/blog/how-to-test-react-app-with-node-test-runner.fr.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
---
title: Comment tester une application React avec Node Test Runner
description: Simplifiez et accélérez drastiquement les tests de votre application React en passant à Node Test Runner.
date: 2024-12-10
authors: AugustinMauroy
---

## Introduction

Les tests sont une partie cruciale du développement logiciel, garantissant que votre application se comporte comme prévu. Avec le [Node.js Test Runner](https://nodejs.org/en/learn/test-runner/introduction), vous pouvez intégrer facilement les tests dans votre application [React](https://react.dev). Ce guide vous accompagnera dans le processus de configuration et d'exécution des tests pour une application React en utilisant le Node.js Test Runner.

> Je vous recommande vivement de lire les [guides du Node.js Test Runner](https://nodejs.org/en/learn/test-runner/introduction) pour comprendre comment fonctionne le test runner de Node.js.
> Ce guide suppose que vous avez une compréhension de base de React et des tests.
## Installation des Dépendances

Tout d'abord, vous devez installer les dépendances nécessaires. En plus des dépendances de votre application React, vous aurez besoin des éléments suivants :

```bash
npm install --save-dev @testing-library/react @testing-library/dom jsdom global-jsdom
```

> **Note** : Les autres dépendances que nous utiliserons proviennent de Node.js.
## Écriture du Composant à Tester

Créons un composant React simple que nous allons tester. Ce composant sera un compteur qui incrémente une valeur lorsque l'on clique sur un bouton.

```tsx fileName="src/components/Counter/index.tsx"
'use client';
import { useState } from 'react';
import styles from './index.module.css';
import type { FC } from 'react';

const Counter: FC = () => {
const [count, setCount] = useState(0);

return (
<div className={styles.container}>
<p className={styles.count}>{count}</p>
<button onClick={() => setCount(count + 1)} className={styles.button}>
Increment
</button>
</div>
);
};

export default Counter;
```

<details>
<summary>`index.module.css`</summary>

```css fileName="src/components/Counter/index.module.css"
.container {
@apply flex flex-col items-center justify-center;

.count {
@apply text-4xl;
}

.button {
@apply px-4 py-2 bg-blue-500 text-white rounded-md;
}
}
```
</details>

## Enregistrement des Chargeurs Node.js

Pour gérer TypeScript et les modules CSS, vous devez enregistrer les chargeurs appropriés. Créez un fichier nommé `node-hooks/react-test.js` et ajoutez le code suivant :

> Pour comprendre ce qu'est un chargeur, consultez [cet article](/blog/post/how-to-use-nodejs-loader).
Vous devrez enregistrer les chargeurs pour TypeScript et les modules CSS :

Tout d'abord, installons les chargeurs :

```bash
npm add -D @nodejs-loaders/tsx @nodejs-loaders/css-module
```

Ensuite, créez le fichier d'enregistrement :

```mjs fileName="node-hooks/react-test.js"
import { register } from 'node:module';
import { pathToFileURL } from 'node:url';
import jsdom from 'global-jsdom';

// Enregistrer les chargeurs
register('@nodejs-loaders/tsx', pathToFileURL('./'));
register('@nodejs-loaders/css-module', pathToFileURL('./'));

jsdom(undefined, {
// ⚠️ Ne pas spécifier cela entraînera probablement de nombreux 🤬
url: 'https://test.example.com',
});
```

## Écriture du Test

Maintenant, écrivons un test pour le composant `Counter`. Créez un fichier nommé `index.test.tsx` dans le même répertoire que votre composant :

```tsx fileName="src/components/Counter/index.test.tsx"
import assert from 'node:assert/strict';
import { describe, it } from 'node:test';
import { render, fireEvent, screen } from '@testing-library/react';
import Counter from './index.ts'; // ⚠️ Nous devons importer le fichier avec l'extension .ts

describe('Counter', () => {
it('should increment the count when the button is clicked', () => {
const { unmount } = render(<Counter />);

const button = screen.getByRole('button', { name: /increment/i });
const count = screen.getByText('0');

assert.strictEqual(count.textContent, '0');

fireEvent.click(button);

assert.strictEqual(count.textContent, '1');

// ⚠️ Il est bon de démonter le composant pour éviter qu'il ne se propage dans le DOM d'autres tests
unmount();
});
});
```

### Structure d'un Fichier de Test

Une structure typique de fichier de test inclut :

1. **Imports** : Importez les modules et composants nécessaires.
2. **Suite de Tests** : Définissez une suite de tests en utilisant `describe`.
3. **Cas de Test** : Définissez des cas de test individuels en utilisant `it`.
4. **Rendu du Composant** : Rendez le composant à tester.
5. **Actions** : Simulez les interactions utilisateur ou d'autres actions.
6. **Assertions** : Faites des assertions pour vérifier le comportement attendu.
7. **Démontage du Composant** : Nettoyez en démontant le composant.

## Exécution du Test

Pour exécuter le test, utilisez la commande suivante :

```bash
node --test --import="./node-hooks/typescript.js" --import="./node-hooks/react.js" **/*.test.tsx
```

Vous pouvez également ajouter un script à votre `package.json` pour simplifier l'exécution des tests :

```json fileName="package.json"
{
"scripts": {
"test:unit": "node --test --import=\"./node-hooks/typescript.js\" --import=\"./node-hooks/react.js\" **/*.test.tsx",
"test:watch": "node --run test:unit --watch"
}
}
```

> **Note** : Vous pouvez ajouter plus de motifs au modèle de glob pour tester plus de fichiers. Par exemple, `**/*.test.ts` pour tester tous les fichiers TypeScript.
Et ensuite pour appeler le script, vous pouvez utiliser `--run` :

```bash
node --run test:unit # ou node --run test:watch
```

## Conclusion

Tester votre application React avec le Node.js Test Runner est un processus simple. En suivant les étapes décrites dans ce guide, vous pouvez vous assurer que vos composants se comportent comme prévu. Bon test !

0 comments on commit 2641754

Please sign in to comment.