Une extension d’événementiel que nous maintenons affiche un texte du type « 3 places restantes ». En français, la fonction _n() suffit avec ses deux formes, singulier et pluriel. Le jour où un client a demandé une version polonaise de l’extension, le texte affichait « 3 miejsce » au lieu de « 3 miejsca », une faute évidente pour n’importe quel locuteur polonais, alors que la chaîne anglaise d’origine et sa traduction française fonctionnaient parfaitement.
Le problème ne venait pas de la fonction _n() elle-même, correctement utilisée, mais du fichier de traduction polonais, qui ne déclarait que deux formes plurielles au lieu des trois requises par cette langue. Aucun test n’aurait détecté ce défaut en ne vérifiant que le français et l’anglais : il fallait un test spécifique par langue cible.
Comprendre les formules de pluriel au-delà du français
Le français et l’anglais suivent une règle simple : une forme pour 0 ou 1, une autre pour le reste. Beaucoup d’autres langues ne s’y conforment pas :
- Polonais : trois formes, selon que le nombre se termine par 1 (hors 11), par 2 à 4 (hors 12-14), ou tout le reste.
- Arabe : six formes distinctes, couvrant zéro, un, deux, un intervalle de 3 à 10, un intervalle de 11 à 99, et le reste.
- Russe : trois formes, avec une logique proche du polonais mais des seuils différents.
Ces formules sont déclarées dans l’en-tête de chaque fichier .po via la directive Plural-Forms, par exemple pour le polonais :
"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
Écrire un test qui vérifie chaque forme, pas seulement deux valeurs

Le test doit charger le domaine de traduction dans la locale ciblée, puis appeler _n() avec des nombres représentatifs de chaque forme grammaticale, pas seulement 1 et 2 comme on le ferait par réflexe pour le français.
class Test_Pluralisation_Polonais extends WP_UnitTestCase {
public function set_up() {
parent::set_up();
switch_to_locale( 'pl_PL' );
}
public function tear_down() {
switch_to_locale( 'fr_FR' );
parent::tear_down();
}
public function data_formes_polonaises() {
return [
'forme singulier (1)' => [ 1, 'miejsce' ],
'forme peu nombreuse (3)' => [ 3, 'miejsca' ],
'forme peu nombreuse (4)' => [ 4, 'miejsca' ],
'forme générale (5)' => [ 5, 'miejsc' ],
'forme générale (12)' => [ 12, 'miejsc' ],
'forme générale (22)' => [ 22, 'miejsc' ],
];
}
/**
* @dataProvider data_formes_polonaises
*/
public function test_chaque_forme_plurielle_est_correcte( $nombre, $mot_attendu ) {
$texte = sprintf(
_n( '%d place restante', '%d places restantes', $nombre, 'mon-evenementiel' ),
$nombre
);
$this->assertStringContainsString( $mot_attendu, $texte );
}
}
C’est ce test, une fois écrit, qui aurait immédiatement révélé que le fichier .po polonais ne couvrait que deux des trois formes attendues : l’appel avec $nombre = 22 serait retombé par erreur sur la deuxième forme au lieu de la troisième.
Vérifier aussi la formule elle-même, pas seulement le résultat
Un test complémentaire, plus direct, consiste à interroger la formule de pluriel chargée par WordPress pour la locale, via la fonction interne du domaine de traduction, afin de s’assurer qu’elle correspond bien au nombre de formes attendu pour la langue :
$traductions = get_translations_for_domain( 'mon-evenementiel' );
$this->assertSame( 3, $traductions->get_plural_forms_count() );
Automatiser la couverture pour toutes les langues livrées
Plutôt que de dupliquer ce test à la main pour chaque langue, nous maintenons un tableau associatif locale => cas de test rejoué par un fournisseur de données unique, ce qui rend triviale l’ajout d’une nouvelle langue livrée par l’extension : il suffit d’ajouter une entrée avec les nombres représentatifs et les mots attendus.
En résumé
Tester uniquement le français ou l’anglais donne une fausse impression de couverture dès qu’une extension est traduite dans une langue aux règles plurielles plus riches. Le coût d’un test par forme grammaticale est faible comparé au risque de livrer une traduction bancale à des utilisateurs qui, contrairement à l’équipe de développement, remarqueront immédiatement la faute.