# Recueillir le feedback des bêta-testeurs build après build

> Un formulaire de feedback bêta avec un lien personnel par testeur et par build, deux échelles de notation et un résumé hebdomadaire qui montre si chaque build s'est amélioré.

Publié le 2026-10-25 · https://ikiform.com/fr/guides/feedback-form/beta-tester-feedback

Donnez à chaque testeur un lien personnel qui porte un code testeur opaque et le numéro de build, pour que le formulaire sache qui répond et sur quel build sans le demander. Demandez à quoi ils ont utilisé le build, deux notes de 1 à 5 pour la stabilité et l'utilité, et ce qui les a bloqués. Comparez ensuite les builds, pas les réponses individuelles, pour voir si chaque version a fait bouger les chiffres.

## Ce qui change avec le feedback bêta

Le feedback public vient d'inconnus, une seule fois. Le feedback bêta vient du même petit groupe de personnes, encore et encore, sur un logiciel qui change chaque semaine. Une réponse isolée compte moins que la tendance : le build 1.4.0 a-t-il paru plus stable que le 1.3.0 aux mêmes personnes ? Il faut pour cela deux choses qu'un formulaire de feedback normal n'a pas : qui a répondu, et sur quel build.

Demander aux testeurs de taper leur e-mail et leur numéro de version échoue en pratique. Ils oublient la version, la tapent mal ou écrivent « la dernière ». Les deux vont donc dans le lien que vous envoyez, et la page les remplit.

Schéma : La boucle hebdomadaire du feedback bêta, d'un nouveau build au suivant

1. Un nouveau build est distribué au groupe bêta.
2. Un script génère un lien par testeur avec son code et le numéro de build, et vous les envoyez par e-mail.
3. Le testeur ouvre le lien. La page remplit les champs masqués du testeur et du build et affiche le build concerné.
4. Un script de synthèse lit chaque réponse via l'API et fait la moyenne des notes par build.
5. Les blocages des notes les plus basses deviennent la liste des corrections du build suivant.

Comparez les colonnes, pas les lignes. La mauvaise semaine d'un testeur, c'est du bruit ; une baisse dans tout le groupe, c'est une régression.

## Les champs

Formulaire : Beta feedback

- **Code testeur** (`tester`, text, obligatoire)
- **Build** (`build`, text, obligatoire)
- **À quoi avez-vous utilisé ce build ?** (`tried`, textarea, obligatoire)
- **Vous a-t-il paru stable ?** (`stability`, rating, obligatoire)
- **Vous a-t-il été utile ?** (`usefulness`, rating, obligatoire)
- **Si vous ne pouviez plus l'utiliser, que ressentiriez-vous ?** (`would_miss`, radio, obligatoire)
- **Quelque chose vous a bloqué ?** (`blockers`, textarea)

`tester` et `build` sont des inputs masqués remplis depuis le lien. Leurs motifs rejettent tout ce qui ne vient pas d'une vraie invitation.

| Champ | Pourquoi |
| --- | --- |
| `tester` | Un code aléatoire de 10 caractères. Permet de suivre une personne d'un build à l'autre sans mettre son e-mail dans une URL |
| `build` | Relie chaque note à une version. Le motif n'accepte que des versions comme `1.4.0` |
| `tried` | Ce qu'ils ont réellement fait. Sans cela, les notes sont difficiles à interpréter |
| `stability`, `usefulness` | Deux champs `rating`, de 1 à 5. Séparés, car un build stable de la mauvaise chose reste la mauvaise chose |
| `would_miss` | À quel point ils seraient déçus sans. Une part croissante de « Très » est le signe le plus fort que la bêta fonctionne |
| `blockers` | Facultatif, et c'est de là que vient la liste des corrections |

## Créer un lien par testeur

Gardez une simple liste d'e-mails de testeurs dans `testers.txt`. Ce script attribue à chacun un code stable la première fois qu'il le voit, enregistre la correspondance dans `testers.json` et écrit un lien d'invitation par testeur pour le build indiqué. Commencez `testers.json` avec `{}`.

`links.mjs`:

```js
import { randomBytes } from "node:crypto";
import { readFileSync, writeFileSync } from "node:fs";

const BUILD = process.argv[2];
if (!/^\d+\.\d+\.\d+$/.test(BUILD ?? "")) throw new Error("Usage: node links.mjs 1.4.0");

const known = JSON.parse(readFileSync("testers.json", "utf8"));
const emails = readFileSync("testers.txt", "utf8").split(/\r?\n/).map((line) => line.trim().toLowerCase()).filter(Boolean);

for (const email of emails) {
  known[email] ??= randomBytes(5).toString("hex");
}
writeFileSync("testers.json", JSON.stringify(known, null, 2));

const rows = emails.map((email) => {
  const link = new URL("https://example.com/beta/feedback");
  link.searchParams.set("t", known[email]);
  link.searchParams.set("build", BUILD);
  return `${email},${link}`;
});
writeFileSync(`invites-${BUILD}.csv`, ["email,link", ...rows].join("\n"));
console.log(`${rows.length} links for build ${BUILD}`);
```

Envoyez le CSV via le publipostage de votre outil d'e-mailing, ou collez les liens à la main pour un petit groupe. Gardez `testers.json` privé : c'est le seul endroit où un code renvoie à une personne.

## La page de feedback

Placez ceci sur une page `/beta/feedback` de votre site. Elle lit le code et le build depuis le lien, refuse d'afficher le formulaire sans eux et envoie de façon classique. Réglez **Redirect after submit** sur une page de remerciement. Cela fonctionne sur n'importe quel hébergeur statique ou créateur de sites qui autorise un script.

`beta/feedback.html`:

```html
<p id="beta-missing" hidden>This page needs the link from your invite email.</p>

<form id="beta" action="https://ikiform.com/f/frm_xxxxxxxxxxxxxxxx" method="post" hidden>
  <h2>Feedback for build <span id="beta-build"></span></h2>
  <input type="hidden" name="tester" />
  <input type="hidden" name="build" />
  <label for="tried">What did you use this build for?</label>
  <textarea id="tried" name="tried" rows="4" required minlength="15"></textarea>
  <fieldset>
    <legend>How stable did it feel?</legend>
    <label><input type="radio" name="stability" value="1" required /> 1, it crashed a lot</label>
    <label><input type="radio" name="stability" value="2" /> 2</label>
    <label><input type="radio" name="stability" value="3" /> 3</label>
    <label><input type="radio" name="stability" value="4" /> 4</label>
    <label><input type="radio" name="stability" value="5" /> 5, no problems</label>
  </fieldset>
  <fieldset>
    <legend>How useful was it?</legend>
    <label><input type="radio" name="usefulness" value="1" required /> 1, not at all</label>
    <label><input type="radio" name="usefulness" value="2" /> 2</label>
    <label><input type="radio" name="usefulness" value="3" /> 3</label>
    <label><input type="radio" name="usefulness" value="4" /> 4</label>
    <label><input type="radio" name="usefulness" value="5" /> 5, I rely on it</label>
  </fieldset>
  <fieldset>
    <legend>If you could no longer use it, how would you feel?</legend>
    <label><input type="radio" name="would_miss" value="very" required /> Very disappointed</label>
    <label><input type="radio" name="would_miss" value="somewhat" /> Somewhat disappointed</label>
    <label><input type="radio" name="would_miss" value="not" /> Not disappointed</label>
  </fieldset>
  <label for="blockers">Anything that stopped you?</label>
  <textarea id="blockers" name="blockers" rows="3"></textarea>
  <input name="_gotcha" type="text" tabindex="-1" autocomplete="off" hidden />
  <button>Send this week's feedback</button>
</form>

<script>
  const params = new URLSearchParams(location.search);
  const tester = params.get("t") ?? "";
  const build = params.get("build") ?? "";
  const form = document.getElementById("beta");
  if (/^[a-z0-9]{10}$/.test(tester) && /^\d+\.\d+\.\d+$/.test(build)) {
    form.elements.tester.value = tester;
    form.elements.build.value = build;
    document.getElementById("beta-build").textContent = build;
    form.hidden = false;
  } else {
    document.getElementById("beta-missing").hidden = false;
  }
</script>
```

> Toute personne qui a le lien d'un testeur peut répondre à sa place. C'est acceptable pour une bêta : les codes sont aléatoires, le groupe est petit et une réponse bizarre se remarque. N'utilisez pas le code pour donner accès à quoi que ce soit.

## Comparer les builds

Le tableau de bord affiche les réponses une par une. Pour comparer les builds, lisez-les toutes avec le SDK et regroupez par `build`. Lancez ceci avec une clé secrète dans `IKIFORM_SECRET_KEY` :

`summary.mjs`:

```js
import { createClient } from "@ikiform/sdk";

const ikiform = createClient({ apiKey: process.env.IKIFORM_SECRET_KEY });
const builds = new Map();

for await (const submission of ikiform.submissions.iterate({ formId: "frm_xxxxxxxxxxxxxxxx", status: "received" })) {
  const { build, tester, stability, usefulness, would_miss } = submission.fields;
  const row = builds.get(build) ?? { testers: new Set(), stability: 0, usefulness: 0, very: 0, answers: 0 };
  row.testers.add(tester);
  row.stability += stability;
  row.usefulness += usefulness;
  row.very += would_miss === "very" ? 1 : 0;
  row.answers += 1;
  builds.set(build, row);
}

console.table(
  [...builds].map(([build, row]) => ({
    build,
    testers: row.testers.size,
    stability: (row.stability / row.answers).toFixed(1),
    usefulness: (row.usefulness / row.answers).toFixed(1),
    "very disappointed": `${Math.round((row.very / row.answers) * 100)}%`,
  })),
);
```

Les notes arrivent sous forme de nombres, donc les moyennes ne demandent aucun parsing. Affichez le nombre de testeurs à côté de chaque moyenne : un build avec trois réponses ne se compare pas honnêtement à un build qui en a trente.

## Vérifiez que tout fonctionne

1. Lancez `node links.mjs 1.4.0` et ouvrez l'un des liens. Le formulaire affiche "Feedback for build 1.4.0".
2. Ouvrez la page sans les paramètres d'URL. Seul le message d'invitation s'affiche.
3. Envoyez une réponse, puis changez `build` en `latest` dans les outils de développement du navigateur et envoyez à nouveau. Ikiform répond `422` avec "Use a version like 1.4.0".
4. Lancez `summary.mjs`. Le tableau affiche le build 1.4.0 avec un testeur et vos deux notes.

## Pièges

- Les groupes bêta testent souvent depuis un même bureau, qui partage une IP. La limite Standard les compte ensemble : choisissez donc Relaxed, 20 par minute et par visiteur, pour ce formulaire.
- Les bêtas mobiles sur TestFlight permettent déjà aux testeurs d'envoyer un feedback avec capture d'écran à App Store Connect. Utilisez-le pour les bugs d'écran et ce formulaire pour les questions hebdomadaires.
- Posez les mêmes questions chaque semaine. Changer la formulation casse la comparaison entre les builds.
- Les testeurs répondent de moins en moins au fil de la bêta. Gardez le formulaire à quelques minutes, et remerciez les gens par leur nom dans les notes de version.
- Ikiform ne fusionne pas les réponses répétées. Si un testeur répond deux fois pour un même build, gardez la plus récente dans votre synthèse.

## Dépannage

| Problème | Que faire |
| --- | --- |
| `422` avec "Open the link from your invite email" | La valeur `tester` ne correspond pas au motif, généralement parce que le lien a été coupé dans un client e-mail. Renvoyez le lien. |
| `429 rate_limited` | Un visiteur a envoyé plus que ce que permet la limite de débit du formulaire. Standard autorise 5 envois par minute et par visiteur. Attendez la durée de `Retry-After`, ou choisissez Relaxed ou Custom pour les formulaires qui envoient depuis une seule IP partagée. |
| `403 origin_not_allowed`, ou tous les envois finissent en spam | Le domaine de la page n'est pas dans les **Allowed domains** du formulaire. Ajoutez-le, plus `localhost` pour les tests en local. Les sous-domaines d'un domaine listé sont autorisés. |

## Questions

### Comment savoir quel bêta-testeur a envoyé un feedback ?

Donnez à chaque testeur un code aléatoire et mettez-le dans son lien personnel. La page le copie dans un champ masqué, et seul votre fichier de correspondance privé relie le code à un e-mail.

### Comment suivre le feedback par build ?

Mettez aussi le numéro de build dans le lien, validez-le avec un motif et regroupez les réponses par build. La méthode submissions.iterate du SDK lit chaque réponse pour une synthèse.

### Quelles questions doit poser un formulaire de feedback bêta ?

À quoi ils ont utilisé le build, à quel point il leur a paru stable et utile sur une échelle de 1 à 5, à quel point ils seraient déçus sans, et ce qui les a bloqués. Gardez les mêmes questions chaque semaine.

### Les bêta-testeurs doivent-ils signaler les bugs dans le même formulaire ?

Gardez un formulaire de signalement de bug à part pour tout ce qui doit être reproduit. Le formulaire hebdomadaire porte sur le ressenti global du build ; mélanger les deux rend chacun plus difficile à lire.

## Autres guides

- [Formulaire de feedback pour un site ou une application](https://ikiform.com/fr/guides/feedback-form.md): Placez un formulaire de feedback sur n'importe quelle page ou dans votre application : une note, un commentaire, la page d'origine, le filtrage du spam et des alertes quand une note est basse.
- [Formulaire de signalement de bug](https://ikiform.com/fr/guides/feedback-form/bug-report.md): Un formulaire de signalement de bug qui demande les étapes et la gravité, et laisse la page ajouter elle-même l'URL, le navigateur, le viewport et les erreurs récentes.
- [Enquête NPS](https://ikiform.com/fr/guides/feedback-form/nps-survey.md): Menez une enquête NPS avec un score de 0 à 10 dans l'e-mail, une question de suivi sur votre propre page qui change selon le score, et un script qui calcule le NPS.
- [Formulaire de demande de fonctionnalité](https://ikiform.com/fr/guides/feedback-form/feature-request.md): Un formulaire de demande de fonctionnalité qui demande le problème plutôt que la solution, range les demandes par thème, compte les personnes et non les lignes, et les prévient quand c'est livré.
- [Widget de feedback React](https://ikiform.com/fr/guides/feedback-form/react-feedback-widget.md): Un bouton de feedback flottant pour une application React qui ouvre un petit panneau, envoie l'écran, la version et le compte avec chaque réponse, et ne perd jamais un brouillon.
- [Enquête de résiliation](https://ikiform.com/fr/guides/feedback-form/cancellation-survey.md): Demandez pourquoi vos clients résilient dans le parcours d'annulation de votre SaaS, gardez Passer à un clic, enregistrez la raison dans Stripe et Ikiform, sans jamais retarder la résiliation.
