Migrating from Legacy Systems

Intégrer un ingénieur de test en une semaine

Comment amener un ingénieur Python sans expérience du test de l'installation du CLI à un vrai poste, avec runs remontés et revue du FPY, en cinq jours.

JJulien Buteau
beginner9 min de lecture23 septembre 2026

Un ingénieur Python sans expérience du test en fabrication peut prendre la responsabilité d'un poste en une semaine quand le framework fournit le séquenceur, les limites, l'interface opérateur et la plateforme de données. Les cinq jours ci-dessous amènent une nouvelle recrue de l'installation du CLI à l'exécution d'un vrai poste avec --upload et à la revue du FPY avec son responsable. Ce qu'elle apprend en chemin, c'est le produit et les instruments, la partie qu'aucun framework ne peut fournir.

Ce que le responsable prépare à l'avance

La semaine cale dès le lundi matin s'il manque l'un de ces éléments.

  • Un compte et une clé API. La recrue a besoin de son propre login sur l'organisation TofuPilot, et le poste a besoin d'une clé API pour les remontées. L'offre Lab est gratuite.
  • Une procedure créée dans l'application. Créez-la avant lundi et notez son nom. Le jour 1 y lie le template, le jour 5 y lie le vrai poste.
  • Un poste avec un instrument sur le réseau. Un DMM ou un DAQ de banc avec un port LAN, une adresse VISA connue et un câble vers le DUT. S'il n'a que du GPIB ou de l'USB, installez le driver VISA du fabricant sur le PC du poste avant l'arrivée de la recrue.
  • Une unité bonne connue et une mauvaise connue. Une unité qui passe, une avec un défaut documenté. Les jours 3 et 5 sont bien plus courts avec les deux sur le banc.
  • Un binôme. La personne qui fait tourner le poste aujourd'hui, réservée une heure par jour. Pas le responsable.
  • La liste des mesures incontournables du produit. Les cinq mesures qui décident entre expédier et rebuter, avec leurs limites, sur une page.

La fiche de poste qui vous a amené cette recrue liste probablement déjà ce qu'elle sait. Fiche de poste d'ingénieur de test pour recruter en Python est la version qui correspond à cette semaine.

La semaine, jour par jour

JourTâcheLivrableCe qu'elle apprend
1Installer le CLI, cloner le template fct-fixture, l'exécuter avec des plugs mock, remonter un runUne page de run dans TofuPilot à son nomCe que sont une procedure, une phase, un plug et un run
2Remplacer un plug mock par un vrai instrument via PyVISAUne mesure de rail depuis du vrai matérielSCPI, adresses VISA, pourquoi les instruments renvoient des chaînes
3Ajouter une phase avec une mesure et des limitesUne phase qui passe sur la bonne unité et échoue sur la mauvaiseValidateurs, clés de mesure, comment un échec se propage
4Suivre un opérateur pendant une heure, puis ajouter de l'interface opérateur à la procedureUne checklist et des instructions demandées par l'opérateurCe que fait l'atelier entre deux runs
5Exécuter un vrai poste avec --upload, revoir le FPY avec le responsableVingt runs remontés et une première conversation sur le rendementComment son code devient les chiffres de l'usine

Jour 1 : exécuter le template

Le template fct-fixture est un poste de test fonctionnel PCBA complet avec des instruments mock. Il tourne sur un portable sans matériel branché.

day1.sh
# Installer le CLI, exécuter le template en local, puis le lier et remonter un runcurl -fsSL https://www.tofupilot.app/install | shgit clone https://github.com/tofupilot/template-framework-fct-fixturecd template-framework-fct-fixturetofupilot run ./procedure.yamltofupilot logintofupilot linktofupilot run ./procedure.yaml --upload

Le premier tofupilot run ne demande aucun compte. Faites lire procedure.yaml de haut en bas à la recrue avant le second : unit, plugs, setup, main, teardown. Puis ouvrez le run remonté dans TofuPilot et faites correspondre chaque phase de la page à son bloc dans le fichier. Cette correspondance, c'est l'essentiel du jour 1. La page du template explique à quoi sert chaque phase.

Jour 2 : remplacer un plug mock par un vrai instrument

Le plug daq du template est un mock qui couvre les rails, la boucle GPIO, un AWG et des photodiodes. La recrue ne le remplace pas entièrement. Elle sous-classe le mock et ne redéfinit que la lecture des rails avec le DMM du banc, pour que toutes les autres phases continuent de tourner sur des données mock jusqu'à ce que la vraie montage existe.

plugs/bench_daq.py
20 lines
# Jour 2 : vraies lectures de rails via PyVISA ; tout le reste reste mock jusqu'à l'arrivée de la fixtureimport pyvisafrom plugs.daq import FixtureDaqRAIL_CHANNEL = {"3v3": 101, "5v": 102, "1v8": 103}class BenchDaq(FixtureDaq):    def __init__(self, address="TCPIP::192.168.1.100::INSTR"):        super().__init__()        self.inst = pyvisa.ResourceManager("@py").open_resource(address)        self.inst.timeout = 5000    def measure_rail(self, name):        self.inst.write(f"ROUT:CLOS (@{RAIL_CHANNEL[name]})")        return float(self.inst.query(":MEAS:VOLT:DC?"))    def close(self):        self.inst.close()
procedure.yaml
# Pointer la clé daq vers la nouvelle classe ; les phases ne changent pasplugs:  - name: Fixture DAQ    key: daq    python: plugs.bench_daq:BenchDaq    config:      address: "TCPIP::192.168.1.100::INSTR"

Relancez. Les trois mesures de rails viennent maintenant du DMM, et la page de run dans TofuPilot montre de vraies valeurs à côté des valeurs mock de lundi. La leçon du jour 2, c'est le float() : tout ce que VISA renvoie est une chaîne, et la conversion a sa place dans le plug, pas dans la phase. La documentation PyVISA couvre le reste.

Jour 3 : ajouter une phase avec une mesure et des limites

Prenez une ligne de la liste des mesures incontournables du responsable que le template ne couvre pas encore. Le template vérifie l'ondulation sur le rail 3V3, ajoutez-la donc sur le rail 5 V, après la mise sous tension.

procedure.yaml
# Jour 3 : une nouvelle phase, une mesure, deux validateurs, s'exécute après power_onmain:  - name: Rail Ripple    key: rail_ripple    python: phases.rail_ripple    depends_on: [power_on]    measurements:      - name: ripple_5v        unit: mV        validators:          - operator: ">="            expected_value: 0          - operator: "<="            expected_value: 50
phases/rail_ripple.py
# La phase assigne la valeur ; procedure.yaml décide du pass ou du faildef rail_ripple(measurements, daq):    measurements.ripple_5v = daq.measure_ripple_mv("5v")

Exécutez-la sur la bonne unité, puis sur la mauvaise. Pass, puis fail, et la page de run montre quel validateur a déclenché. Les clés comptent ici : ripple_5v dans le YAML est measurements.ripple_5v en Python, et le tableau de bord regroupe l'historique par cette clé, donc choisissez-la une fois et ne la renommez pas.

Jour 4 : suivre un opérateur, puis ajouter de l'interface opérateur

Matin : une heure dans l'atelier avec le binôme, à regarder trois unités passer. La recrue note ce que l'opérateur vérifie à l'œil, ce qu'il fait qui n'est pas dans la procedure, et ce qu'il voudrait voir à l'écran. L'opérateur connaît la nappe UART qui se déconnecte depuis un an. Le jour 4, c'est quand quelqu'un l'écrit.

Après-midi : déclarez-le. L'interface opérateur dans le framework, c'est du YAML, pas du code frontend.

procedure.yaml
22 lines
# Jour 4 : ce que l'opérateur a demandé, déclaré en YAML, sans Python derrièremain:  - name: Fixture Setup    key: fixture_setup    ui:      requires_input: true      components:        - key: instructions          type: text          label: "Before closing the lid"          default_value: "Seat the board on the four locating pins, then connect the UART ribbon with the red stripe toward the board edge."        - key: setup_checks          type: checklist          label: "Setup checks"          required: true          options:            - label: "Board seated on all four pins"              value: "seated"            - label: "UART ribbon connected, red stripe out"              value: "uart"            - label: "ESD strap on"              value: "esd"

La phase n'a pas de Python. Le framework affiche le texte, attend la checklist et passe à la suite. La recrue apprend le jour 4 qu'une bonne part des pertes de rendement vient de la manipulation de le montage, et que le correctif est souvent une phrase à l'écran, pas un changement de limite. Documenter un poste de test pour la passation est là où ces phrases finissent.

Jour 5 : prendre en charge un poste

Matin : le vrai poste, avec le vrai DUT, lié à la procedure de production. Vingt unités, bonnes et mauvaises mélangées.

day5.sh
# Le vrai poste, lié à la procedure de production, qui remonte chaque runtofupilot link ./stations/fct-01 --procedure "Controller Board FCT"tofupilot run ./stations/fct-01/procedure.yaml --upload

Après-midi : asseyez-vous avec le responsable, ouvrez la procedure dans TofuPilot et lisez trois choses ensemble : le FPY, le Pareto des défaillances et l'histogramme de la mesure du jour 3. Trois questions à poser. Quelle phase échoue le plus, et est-ce une limite ou un montage ? La limite d'ondulation est-elle trop serrée pour ce que montre l'histogramme ? Quel est le Cpk sur les mesures de rails maintenant qu'elles viennent de vrai matériel ?

Ne demandez pas à la recrue de calculer le FPY. TofuPilot le suit, et l'exercice consiste à le lire et à demander pourquoi. Vendredi après-midi, elle a écrit un plug, une phase et un écran opérateur, remonté de vrais runs et eu une conversation sur le rendement. C'est ça, la prise en charge. La Checklist des compétences Python pour ingénieurs de test est la liste à revoir avec elle le lundi suivant.

Pourquoi c'est une semaine, pas un trimestre

Sur un poste LabVIEW, une nouvelle recrue passe le premier trimestre à apprendre le séquenceur que quelqu'un d'autre a construit, les conventions de la face-avant, le fil d'erreur et les VI de rapport, avant de changer une seule limite. Le framework fournit ces quatre choses, donc les cinq jours ci-dessus les sautent entièrement.

Ce qui reste, c'est le produit et les instruments. Un ingénieur Python sans expérience du test atteint en général le stade « responsable d'un poste » en quelques semaines, pas en quelques mois, quand le séquenceur est fourni. Ce qui fait bouger ce délai, c'est le nombre d'instruments du poste, la connaissance de le montage par le binôme et l'existence de la liste des mesures incontournables avant lundi.

La semaine laisse aussi derrière elle quelque chose qu'un trimestre d'intégration LabVIEW ne laisse pas. Le plug, la phase et l'écran opérateur de la recrue sont des fichiers texte dans un dépôt, relus par le responsable dans une pull request et visibles par la recrue suivante. Intégrer le second ingénieur prend la même semaine, et le poste ne dépend plus jamais du premier.

Commencez par un poste

Choisissez le poste au plus fort volume, ou celui qu'une seule personne sait ouvrir. Reconstruisez-le en Python avec le TofuPilot Framework et faites-le tourner en parallèle de la version LabVIEW sur les mêmes unités pendant deux semaines. Comparez les deux jeux de résultats dans TofuPilot avant de retirer quoi que ce soit.

install-and-run.sh
curl -fsSL https://www.tofupilot.app/install | shtofupilot run ./procedure.yaml

Le pas à pas est dans Migrer de LabVIEW vers Python, et le framework est sur https://tofupilot.com/products/framework. L'offre Lab est gratuite, et tofupilot run fonctionne sans compte.

Plus de guides

Mettez ce guide en pratique