DESCRIBE wp_postmeta; — cette commande, exécutée directement dans une console MySQL, renvoie la liste exacte des colonnes d’une table, leur type et leurs contraintes. La même requête, exécutée depuis un test PHPUnit via $wpdb, permet de figer cette structure et de détecter tout écart avant qu’une montée de version de WordPress ne modifie silencieusement une colonne dont une extension dépend directement.
Ce sujet ne traite pas des révisions de contenu ni des métadonnées elles-mêmes : il porte sur la table dans sa structure, pas sur les données qu’elle contient.
Pourquoi une extension peut dépendre d’un schéma précis
La majorité des extensions passent par les fonctions de l’API WordPress (get_post_meta(), update_option()) sans jamais interroger directement la structure des tables sous-jacentes, ce qui les rend insensibles à un changement de schéma tant que l’API elle-même reste stable. Certaines extensions, en revanche, exécutent des requêtes SQL directes via $wpdb->get_results() pour des raisons de performance ou de reporting avancé, en s’appuyant sur des colonnes précises par leur nom et leur type. Ce sont ces extensions-là qui prennent un risque réel si une montée de version de WordPress modifie une colonne qu’elles interrogent directement.
Le test qui fige le schéma attendu
class SchemaPostmetaTest extends WP_UnitTestCase
{
public function test_la_structure_de_wp_postmeta_est_celle_attendue(): void
{
global $wpdb;
$colonnes = $wpdb->get_results("DESCRIBE {$wpdb->postmeta}", ARRAY_A);
$nomsEtTypes = array_map(
static fn(array $colonne): string => $colonne['Field'] . ':' . $colonne['Type'],
$colonnes
);
$attendu = [
'meta_id:bigint(20) unsigned',
'post_id:bigint(20) unsigned',
'meta_key:varchar(255)',
'meta_value:longtext',
];
$this->assertSame($attendu, $nomsEtTypes);
}
}

Ce test échoue dès qu’une colonne change de nom, de type, ou d’ordre, ou dès qu’une colonne disparaît ou apparaît de façon inattendue. L’échec, sur une montée de version de WordPress en environnement de test, arrive avant la mise en production, avec un message d’erreur qui pointe directement vers la colonne en cause plutôt que vers une requête SQL qui échouerait silencieusement ou renverrait des valeurs incohérentes.
Où placer ce type de test dans une routine de montée de version
- Exécuter la suite complète, ce test de schéma inclus, sur l’environnement de test avec la nouvelle version de WordPress installée, avant tout déploiement.
- En cas d’échec du test de schéma, consulter le journal des modifications de la nouvelle version pour identifier si le changement de colonne est documenté ou s’il s’agit d’un effet de bord non annoncé.
- Mettre à jour la requête SQL directe de l’extension pour s’adapter à la nouvelle structure, puis mettre à jour la valeur attendue dans le test, jamais l’inverse.
Une limite à connaître
Ce test protège contre un changement de structure, pas contre un changement de comportement à structure identique : une colonne qui garde le même nom et le même type, mais dont la signification change (une réutilisation de champ à d’autres fins), échappe totalement à ce type de vérification. Ce cas plus rare nécessite un test fonctionnel distinct, portant sur le contenu réellement stocké, pas sur la structure de la table qui l’accueille.
Étendre l’approche à plusieurs tables sensibles
Une extension qui interroge directement plusieurs tables du cœur (par exemple wp_posts et wp_postmeta simultanément) gagne à dupliquer ce test de schéma pour chaque table concernée, plutôt que de se limiter à celle jugée la plus à risque. Le coût d’exécution de ce type de test reste négligeable : une seule requête DESCRIBE par table, comparée à un tableau figé dans le code du test.
En résumé
Un test qui interroge directement la structure d’une table via DESCRIBE ou SHOW COLUMNS, puis compare le résultat à une structure attendue figée dans le code, détecte tout changement de schéma introduit par une montée de version de WordPress avant qu’il n’atteigne la production. Ce filet de sécurité reste peu coûteux à écrire et à exécuter, et concerne spécifiquement les extensions qui interrogent directement les tables du cœur plutôt que de passer exclusivement par l’API officielle.