diff --git a/ecrire/tests/Squelettes/Balise/DoublonsTest.php b/ecrire/tests/Squelettes/Balise/DoublonsTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..0147ad8d58dbe82ab873251d52d7c2215e21f407
--- /dev/null
+++ b/ecrire/tests/Squelettes/Balise/DoublonsTest.php
@@ -0,0 +1,41 @@
+<?php
+
+declare(strict_types=1);
+
+namespace Spip\Test\Squelettes\Balise;
+
+use Spip\Test\SquelettesTestCase;
+
+class DoublonsTest extends SquelettesTestCase
+{
+
+	/**
+	 * Test pour la gestion de `#DOUBLONS`
+	 *
+	 * `#DOUBLONS{mots}` ou `#DOUBLONS{mots,famille}`
+	 * donne l'etat des doublons `(MOTS)` à cet endroit
+	 * sous forme de tableau d'id_mot  `array(1,2,3,...)`
+	 *
+	 * `#DOUBLONS` tout seul donne la liste brute de tous les doublons
+	 * `#DOUBLONS*{mots}` donne la chaine brute `",1,2,3,..."`
+	 * (changera si la gestion des doublons evolue)
+	 */
+	public function testBaliseDoublons(): void {
+		$skel = <<<SPIP
+			#SET{d,''}
+			<BOUCLE_t(ARTICLES) />[(#TOTAL_BOUCLE|<{2}|?{NA})]<//B_t>
+			<BOUCLE_a(ARTICLES){par hasard}{0,2}{doublons test}>
+				#SET{d,#GET{d}|concat{','}|concat{#ID_ARTICLE}}
+			</BOUCLE_a>
+			[(#DOUBLONS|count|=={1}|?{'', 'erreur doublons 1'})]
+			[(#DOUBLONS{articles}|count|?{'erreur doublons 2 non vide'})]
+			[(#DOUBLONS{articles,test}|=={
+				#GET{d}|explode{","}|array_filter
+			}|?{'','erreur doublons 3'})]
+			[(#DOUBLONS*{articles,test}|=={#GET{d}}|?{'','erreur doublons*'})]
+			OK
+		SPIP;
+		$this->assertOkCode($skel);
+	}
+
+}
diff --git a/ecrire/tests/legacy/unit/balises/doublons.html b/ecrire/tests/legacy/unit/balises/doublons.html
deleted file mode 100644
index d4de04b02e04f49208446a0dccbec2443bea7f2b..0000000000000000000000000000000000000000
--- a/ecrire/tests/legacy/unit/balises/doublons.html
+++ /dev/null
@@ -1,33 +0,0 @@
-[(#REM)
-
-	Gestion des doublons :
-	// # DOUBLONS{mots} ou #DOUBLONS{mots,famille}
-	// donne l'etat des doublons (MOTS) a cet endroit
-	// sous forme de tableau d'id_mot  array(1,2,3,...)
-	// # DOUBLONS tout seul donne la liste brute de tous les doublons
-	// # DOUBLONS*{mots} donne la chaine brute ",1,2,3,..."
-	// (changera si la gestion des doublons evolue)
-
-]#SET{d,''}
-<BOUCLE_t(ARTICLES) />[(#TOTAL_BOUCLE|<{2}|?{NA})]<//B_t>
-
-<BOUCLE_a(ARTICLES){par hasard}{0,2}{doublons test}>
-	#SET{d,#GET{d}|concat{','}|concat{#ID_ARTICLE}}
-</BOUCLE_a>
-
-
-[(#DOUBLONS|count|=={1}|?{'', 'erreur doublons 1'})]
-
-
-[(#DOUBLONS{articles}|count|?{'erreur doublons 2 non vide'})]
-
-
-[(#DOUBLONS{articles,test}|=={
-	#GET{d}|explode{","}|array_filter
-	}|?{'','erreur doublons 3'})]
-
-
-[(#DOUBLONS*{articles,test}|=={#GET{d}}|?{'','erreur doublons*'})]
-
-
-OK