OpenHTF et le framework TofuPilot sont les deux frameworks Python open-source pensés spécifiquement pour le test de production hardware. OpenHTF a été conçu par Google en 2016 et reste l'option établie, largement déployée. Le framework TofuPilot est plus récent, bâti sur un moteur d'exécution en Rust pour le parallélisme. Les deux modélisent un test comme une suite de phases ordonnées avec des mesures structurées, les deux connectent les instruments via des plugs réutilisables, et les deux tournent nativement sur le CLI TofuPilot en streamant vers le même dashboard. Ce guide les compare côte à côte avec du vrai code pour vous aider à faire le bon choix.
Vue d'ensemble
| Framework TofuPilot | OpenHTF | |
|---|---|---|
| Langage | Python (moteur Rust) | Python |
| Licence | MIT | Apache 2.0 |
| Mainteneur | TofuPilot | |
| Première version | 2025 | 2016 |
| Modèle d'écriture | Procédure YAML déclarative plus phases et plugs en Python | Python code-first avec décorateurs |
| Exécution | Phases et slots en parallèle | Phases séquentielles |
| Communauté | Récente, plus petite | Établie, base installée plus large |
Comparaison des fonctionnalités
| Fonctionnalité | Framework TofuPilot | OpenHTF |
|---|---|---|
| Phases | Oui | Oui |
| Mesures numériques, texte, booléennes | Oui | Oui |
| Logs et pièces jointes | Oui | Oui |
| Identification par numéro de série | Oui | Oui |
| Sous-unités (composants enfants) | Oui | Oui |
| Plugs (connexions instruments partagées) | Oui | Oui |
| Mesures multi-dimensionnelles (waveforms, sweeps) | Oui | Oui |
| Agrégations (moyenne, min, max, écart-type sur tableaux) | Oui | Non |
| Validators par axe (valider la forme d'une courbe) | Oui | Non |
| Prompts opérateur | Oui | Oui |
| Formulaires et composants d'affichage personnalisés | Oui | Non |
| Retry, timeout, setup/teardown | Oui | Oui |
| Exécution conditionnelle | Oui | Oui |
| Phases parallèles | Oui | Non |
| Exécution multi-slot (plusieurs cartes sur un banc) | Oui | Non |
Sur le modèle de données partagé, les deux sont proches de la parité. Les écarts se concentrent sur trois axes : l'analyse avancée des mesures, l'UI opérateur, et l'exécution.
Le même test dans les deux frameworks
Un test fonctionnel qui vérifie le rail 3,3 V et la version firmware d'une carte, écrit dans chaque framework.
Version framework TofuPilot
Le YAML de procédure déclare la séquence et les limites. Les phases et le plug sont du Python simple que la procédure référence par leur nom.
name: Functional Testversion: 1.0.0unit: serial_number: default_value: "PCBA000001" part_number: default_value: "PCBA-100"plugs: - name: dut python: plugs.dut:Dutmain: - name: Measure Voltage python: phases.measure_voltage measurements: - name: rail_3v3 unit: V validators: - operator: ">=" expected_value: 3.2 - operator: "<=" expected_value: 3.4 - name: Check Firmware python: phases.check_firmware measurements: - name: firmware_version validators: - operator: "==" expected_value: "2.1.0"# Les parametres sont injectes par leur nom : measurements, plus le plug dut.def measure_voltage(measurements, dut): measurements.rail_3v3 = dut.read_voltage()def check_firmware(measurements, dut): measurements.firmware_version = dut.query_firmware()class Dut: """Gere la connexion a l'unite sous test.""" def read_voltage(self) -> float: return 3.31 # Remplacer par une lecture instrument def query_firmware(self) -> str: return "2.1.0" # Remplacer par une requete au DUTLancez-le depuis le dossier de la procédure avec tofupilot run, puis déployez sur une station via un push Git.
Version OpenHTF
OpenHTF attache les mesures et les plugs aux fonctions de phase avec des décorateurs, puis les exécute en séquence.
import openhtf as htffrom openhtf.plugs import BasePlugfrom openhtf.util import unitsclass DutPlug(BasePlug): """Gere la connexion a l'unite sous test.""" def read_voltage(self) -> float: return 3.31 # Remplacer par une lecture instrument def query_firmware(self) -> str: return "2.1.0" # Remplacer par une requete au DUT@htf.measures( htf.Measurement("rail_3v3").in_range(3.2, 3.4).with_units(units.VOLT))@htf.plug(dut=DutPlug)def measure_voltage(test, dut): test.measurements.rail_3v3 = dut.read_voltage()@htf.measures(htf.Measurement("firmware_version").equals("2.1.0"))@htf.plug(dut=DutPlug)def check_firmware(test, dut): test.measurements.firmware_version = dut.query_firmware()def main(): test = htf.Test(measure_voltage, check_firmware, part_number="PCBA-100") test.execute(test_start=lambda: input("Scanner le numero de serie : "))if __name__ == "__main__": main()Le CLI TofuPilot exécute nativement les deux frameworks et streame phases, mesures, logs, pièces jointes et UI opérateur vers le dashboard, sans code supplémentaire d'un côté comme de l'autre.
Différences clés dans le code
| Aspect | Framework TofuPilot | OpenHTF |
|---|---|---|
| Définition de la séquence | Déclarée dans procedure.yaml, séparée de la logique | Ordre des fonctions dans htf.Test(...), dans le code |
| Limites | validators en YAML, stockées comme données | .in_range(3.2, 3.4) chaîné dans le code |
| Injection du plug | Par nom de paramètre (dut) | Par le décorateur @htf.plug(dut=...) |
| Accès aux mesures | measurements.rail_3v3 = ... | test.measurements.rail_3v3 = ... |
| Classe de plug | Classe Python simple | Sous-classe de BasePlug |
Exécution et parallélisme
C'est la différence d'architecture la plus nette.
OpenHTF exécute les phases en séquence sur une seule unité sous test. Pour tester plusieurs cartes ou lancer des étapes indépendantes en parallèle, vous orchestrez cela vous-même, en dehors du framework.
Le framework TofuPilot tourne sur un moteur Rust qui exécute les phases indépendantes en parallèle et ne sérialise que là où vous déclarez un depends_on. Il gère aussi l'exécution multi-slot, le test de plusieurs cartes en parallèle sur un même banc, ce qui réduit directement le temps de cycle sur les lignes à fort volume. Votre code de phase et de plug reste du Python pur, le moteur gère l'ordonnancement.
Si votre goulot d'étranglement est le débit sur un banc qui tient plusieurs DUT, c'est le facteur décisif. Si vous testez une unité à la fois, cela compte moins.
Mesures et UI opérateur
Les deux frameworks capturent des mesures typées avec limites, unités et validators, et tous deux gèrent les mesures multi-dimensionnelles pour waveforms et sweeps. Le framework TofuPilot ajoute deux choses absentes d'OpenHTF : les agrégations (moyenne, min, max, écart-type calculés sur un tableau) et les validators par axe qui vérifient la forme d'une courbe, pas seulement ses extrémités. Pour des sweeps RF, des profils thermiques, ou tout test où la waveform elle-même est la spec, cela supprime du code de liaison.
Les deux embarquent une UI opérateur intégrée. OpenHTF fournit des prompts web pour la saisie opérateur, par exemple scanner un numéro de série. Le framework TofuPilot ajoute des composants de formulaire et d'affichage déclaratifs (texte, nombre, switch, radio, select, multiselect, choix d'image, sliders, progression) que vous définissez dans la procédure sans écrire de frontend.
Quand utiliser le framework TofuPilot
Le framework TofuPilot est le meilleur choix lorsque :
- Votre ligne est limitée par le débit. Les phases parallèles et le multi-slot testent plusieurs cartes à la fois sur un banc et réduisent le temps de cycle. OpenHTF s'exécute en séquence.
- Vous validez des waveforms ou des sweeps. Les agrégations et validators par axe intégrés vérifient la forme de la courbe, pas seulement les extrémités, sans code de liaison.
- Les opérateurs ont besoin de workflows guidés riches. Les formulaires et composants d'affichage déclaratifs s'affichent sur la station sans travail frontend.
- Vous voulez le plan de test séparé de la logique. La procédure YAML est lisible et diffable indépendamment des phases Python.
- Vous montez de nouvelles stations. Deploy-on-push, streaming temps réel et file d'attente offline sont intégrés au CLI.
Quand utiliser OpenHTF
OpenHTF est le meilleur choix lorsque :
- Vous l'utilisez déjà. Les suites OpenHTF existantes tournent nativement sur TofuPilot sans réécriture. Le coût de migration n'en vaut pas la peine.
- La maturité et la communauté priment. Des années d'usage en production à grande échelle et un corpus plus large d'exemples et de patterns publics.
- Vous voulez un paradigme Python pur et unique. Tout est en Python, sans couche YAML séparée à apprendre.
- Apache 2.0 convient à votre revue juridique. Sa concession de brevet explicite peut compter dans certains contextes d'achat.
Utiliser les deux ensemble
Vous n'avez pas à choisir le framework pour choisir la plateforme. Un chemin courant : garder une suite OpenHTF existante telle quelle, et sortir le framework TofuPilot sur les nouvelles stations qui ont besoin de slots parallèles ou de mesures plus riches. Les deux streament phases, mesures, logs, pièces jointes et UI opérateur vers le même dashboard, et les deux sont open-source, donc aucun des deux choix ne verrouille le code de test lui-même.
Matrice de décision
| Question | Meilleur choix |
|---|---|
| Tester plusieurs cartes sur un banc, limité par le débit ? | Framework TofuPilot |
| Valider la forme d'une waveform ou d'un sweep, pas juste les extrémités ? | Framework TofuPilot |
| Besoin de formulaires opérateur riches sur la station ? | Framework TofuPilot |
| Suites OpenHTF déjà en production ? | OpenHTF |
| Paradigme Python pur et unique, sans YAML ? | OpenHTF |
| Maturité et communauté maximales avant tout ? | OpenHTF |
Les deux tournent sur le CLI TofuPilot et remontent vers le même dashboard, donc vous pouvez commencer avec l'un ou l'autre et les mélanger station par station.