# « Error establishing a database connection » dans la suite de tests WordPress

> Pourquoi install-wp-tests.sh échoue ou pourquoi les tests ne trouvent pas la base attendue, avec les correctifs qui marchent en local et en conteneur.

- Auteur : Clément Hadrot
- Publié le : 2022-12-05
- Mis à jour le : 2022-12-05
- Catégorie : Tests
- URL : https://wpmoderne.dev.wordpress-developpement.fr/tests/erreur-connexion-base-donnees-suite-tests/

## L’essentiel

- Vérifier le socket ou l'hôte utilisé par le script d'installation
- WP_TESTS_DOMAIN et wp-tests-config.php doivent rester cohérents
- Un conteneur MySQL non prêt casse le script sans message clair

Symptôme : la commande `vendor/bin/phpunit` renvoie immédiatement une page HTML complète contenant « Error establishing a database connection », comme si un vrai navigateur avait chargé une installation WordPress cassée, plutôt qu'un rapport de test attendu. Le réflexe naturel est de suspecter les identifiants de connexion dans `wp-tests-config.php`, mais la cause la plus fréquente se trouve ailleurs : un décalage entre l'hôte utilisé par le script d'installation et celui réellement joignable depuis l'environnement où tourne PHPUnit.

Diagnostiquer ce type d'échec demande de suivre une méthode plutôt que de changer des paramètres au hasard : identifier précisément où la connexion échoue, avant de corriger.

## Diagnostic : où la connexion échoue-t-elle réellement

La première étape consiste à isoler si le problème vient du script d'installation ou de l'exécution des tests eux-mêmes :

```
bash bin/install-wp-tests.sh wordpress_test root root 127.0.0.1 latest
```

Si cette commande échoue déjà, le problème est en amont de PHPUnit : le serveur MySQL n'est simplement pas joignable avec ces paramètres depuis la machine qui exécute le script. Si elle réussit mais que `vendor/bin/phpunit` échoue ensuite, le problème vient d'une incohérence entre `wp-tests-config.php` et l'environnement réel d'exécution des tests.

## Cause fréquente en local : socket contre TCP

Sur macOS avec MySQL installé via Homebrew, ou sur certaines distributions Linux, le client MySQL en ligne de commande utilise par défaut un socket Unix quand l'hôte est `localhost`, mais bascule en TCP dès que l'hôte est `127.0.0.1`. Si le service MySQL n'écoute que sur l'un des deux, le script échoue selon la valeur exacte passée :

```
# Forcer le TCP explicitement pour éviter l'ambiguïté du socket
bash bin/install-wp-tests.sh wordpress_test root root 127.0.0.1:3306 latest
```

> L'essentiel à retenir : Vérifier le socket ou l'hôte utilisé par le script d'installation ; WP_TESTS_DOMAIN et wp-tests-config.php doivent rester cohérents ; Un conteneur MySQL non prêt casse le script sans message clair

## Cause fréquente en conteneur : le service n'est pas encore prêt

Dans un pipeline d'intégration continue avec un service MySQL démarré en parallèle du job, un délai de quelques secondes existe entre le démarrage du conteneur et le moment où il accepte réellement des connexions. Lancer `install-wp-tests.sh` immédiatement après le démarrage du service échoue de façon intermittente, ce qui rend le bug difficile à reproduire localement :

```
services:
  mysql:
    image: mysql:8.0
    options: >-
      --health-cmd="mysqladmin ping"
      --health-interval=5s
      --health-timeout=3s
      --health-retries=10
```

L'option `health-cmd` attend que `mysqladmin ping` réponde favorablement avant de considérer le service prêt, ce qui élimine la course entre démarrage du conteneur et lancement du script d'installation.

## Vérifier la cohérence de wp-tests-config.php

Une fois la base réellement créée, il faut que `wp-tests-config.php` pointe vers exactement les mêmes paramètres que ceux utilisés pour l'installer :

- `DB_HOST` doit correspondre à l'hôte réellement résolu, pas à celui d'un ancien environnement copié-collé
- `DB_NAME` doit être strictement le même nom de base que celui passé au script d'installation
- En conteneur Docker, `DB_HOST` doit être le nom du service (`mysql`, `db`...), jamais `127.0.0.1`, qui pointerait vers le conteneur exécutant PHP lui-même plutôt que vers le service MySQL

## Prévention

Une fois le problème résolu, documenter dans le `README` du projet la commande exacte d'installation utilisée, avec le port et l'hôte corrects, évite de reproduire le même diagnostic à chaque nouvel arrivant sur le projet. Un script `composer test:setup` qui encapsule ces paramètres reste la protection la plus durable contre ce type d'erreur récurrente.

## Pour aller plus loin

Ce diagnostic couvre l'échec au moment de l'installation ou de la connexion initiale. Les écarts de comportement entre une CI qui passe et un poste local qui échoue pour d'autres raisons — versions de PHP différentes, extensions manquantes — relèvent d'une catégorie de problèmes distincte, à diagnostiquer séparément.
