Migrating from Legacy Systems

Migrer de LabVIEW TestExec vers Python

Guide pratique de migration de LabVIEW TestExec vers l'automatisation de tests en Python avec OpenHTF et TofuPilot, couvrant la correspondance.

JJulien Buteau
intermediate12 min de lecture14 mars 2026

Comment migrer de LabVIEW TestExec vers Python avec TofuPilot

LabVIEW TestExec a rempli son rôle. Mais les coûts de licence ne cessent d'augmenter, trouver des développeurs LabVIEW devient de plus en plus difficile, et votre pipeline CI/CD ne parle pas le langage G. Python vous donne le langage, OpenHTF vous donne le framework de test, et TofuPilot vous donne la plateforme de données.

Voici comment effectuer la transition sans perdre votre couverture de test.

Pourquoi les équipes migrent

Point de frictionLabVIEW TestExecPython + TofuPilot
LicencesPar poste, renouvellement annuelGratuit et open source
Vivier de développeursEn diminution, spécialiséLarge, en croissance
Contrôle de versionVIs binaires, conflits de fusionFichiers texte, Git standard
Intégration CI/CDAdaptateurs personnalisés nécessairesSupport natif pytest/OpenHTF
Pilotes d'instrumentsÉcosystème NI uniquementPyVISA, tout instrument SCPI
Stockage des donnéesFichiers TDM/TDMS locauxBase de données cloud avec API

Prérequis

  • Python 3.8+ installé
  • pip install openhtf tofupilot pyvisa
  • Accès à vos séquences et spécifications de test LabVIEW existantes
  • Documentation des instruments (références de commandes SCPI)

Étape 1 : Mapper votre architecture TestExec

LabVIEW TestExec et OpenHTF partagent des concepts similaires avec des noms différents :

LabVIEW TestExecOpenHTF + TofuPilotNotes
Séquence de testhtf.Test()Conteneur de test de niveau supérieur
Étape de testFonction de phaseFonction Python décorée
LimiteValidateur htf.Measurement.in_range(), .at_most(), etc.
Résultat d'étapeValeur de mesureStockée avec le statut réussite/échec
Fichier de séquence (.seq)Script Python (.py)Texte sous contrôle de version
Interface opérateurInterface station TofuPilotWeb, pas de runtime LabVIEW nécessaire
RapportTableau de bord TofuPilotAutomatique, en temps réel
Variable globale de stationConfig au niveau module ou variable d'envPatterns Python standards

Étape 2 : Convertir les étapes de test en phases Python

Une étape LabVIEW TestExec typique qui lit une tension devient une phase Python :

Avant (pseudo-code LabVIEW TestExec) :

Step: "Read 5V Rail" Type: Numeric Limit Test Instrument: DMM_1 (NI PXI-4072) Command: Measure DC Voltage Low Limit: 4.95 High Limit: 5.05 Units: V

Après (Python avec OpenHTF) :

power_test.py
import openhtf as htf
from openhtf.util import units
import pyvisa

@htf.measures(
    htf.Measurement("voltage_5v_rail")
        .with_units(units.VOLT)
        .in_range(4.95, 5.05)
        .doc("Tension de sortie du rail 5V"),
)
def read_5v_rail(test, dmm):
    """Lire et valider la tension du rail 5V."""
    voltage = float(dmm.query("MEAS:VOLT:DC?"))
    test.measurements.voltage_5v_rail = voltage

Le pattern est toujours le même :

  1. Définir les mesures avec des limites (remplace les colonnes de limites)
  2. Écrire le contrôle d'instrument dans le corps de la phase (remplace le VI)
  3. Assigner les valeurs mesurées (remplace le résultat de l'étape)

Étape 3 : Gérer les connexions d'instruments

LabVIEW TestExec utilise l'architecture de pilotes d'instruments NI. Python utilise PyVISA, qui fonctionne avec NI, Keysight, Rigol et tout instrument compatible SCPI.

instruments.py
import pyvisa

def connect_instruments():
    """Remplacer les variables globales de station TestExec par des connexions PyVISA."""
    rm = pyvisa.ResourceManager()

    instruments = {
        "dmm": rm.open_resource("TCPIP::192.168.1.10::INSTR"),
        "psu": rm.open_resource("TCPIP::192.168.1.11::INSTR"),
        "scope": rm.open_resource("USB0::0x0957::0x1796::INSTR"),
    }

    # Configurer les instruments
    instruments["dmm"].timeout = 5000
    instruments["psu"].write("*RST")

    return instruments

Si vous utilisez des instruments NI PXI, le backend NI-VISA fonctionne avec PyVISA. Vos instruments GPIB, USB et TCP/IP fonctionnent sans aucun logiciel NI.

Étape 4 : Convertir le contrôle de flux de séquence

LabVIEW TestExec dispose d'un contrôle de flux intégré (préconditions, post-actions, branchements). Dans OpenHTF, vous utilisez du Python standard :

Exécution conditionnelle :

conditional_test.py
import openhtf as htf

@htf.measures(
    htf.Measurement("board_variant")
        .with_allowed_values("A", "B", "C"),
)
def detect_variant(test):
    """Lire la variante de carte depuis l'EEPROM ou le pont diviseur résistif."""
    variant = read_board_variant()
    test.measurements.board_variant = variant
    test.state["variant"] = variant

@htf.measures(
    htf.Measurement("bluetooth_rssi")
        .with_units(units.DECIBEL)
        .at_least(-70),
)
def bluetooth_test(test):
    """S'exécute uniquement sur la variante B (cartes équipées Bluetooth)."""
    if test.state.get("variant") != "B":
        return  # Ignorer pour les variantes sans BT

    rssi = scan_bluetooth()
    test.measurements.bluetooth_rssi = rssi

Setup et teardown :

setup_teardown.py
import openhtf as htf

@htf.PhaseOptions(timeout_s=10)
def setup_fixture(test, fixture_controller):
    """Remplace le groupe d'étapes Setup de TestExec."""
    fixture_controller.clamp()
    fixture_controller.connect_probes()

@htf.PhaseOptions(run_if=lambda: True)  # S'exécute toujours
def teardown_fixture(test, fixture_controller):
    """Remplace le groupe d'étapes Cleanup de TestExec. S'exécute même en cas d'échec."""
    fixture_controller.release()
    fixture_controller.disconnect_probes()

Étape 5 : Mettre en place la collecte de données

LabVIEW TestExec stocke les résultats dans des fichiers locaux (TDM, TDMS, XML). TofuPilot stocke tout dans le cloud avec une traçabilité complète.

main_test.py
import openhtf as htf
from tofupilot import TofuPilotClient

def main():
    instruments = connect_instruments()

    test = htf.Test(
        setup_fixture,
        detect_variant,
        read_5v_rail,
        bluetooth_test,
        teardown_fixture,
        phase_kwargs={
            "dmm": instruments["dmm"],
            "psu": instruments["psu"],
        },
    )

    test.add_output_callbacks(
        TofuPilotClient().as_openhtf_callback(
            procedure_id="pcba-fct-v3",
            procedure_name="PCBA FCT (migré depuis TestExec)",
        )
    )

    test.execute(test_start=htf.PhaseDescriptor.wrap(
        lambda test: setattr(test, "dut_id", input("Scanner le numéro de série : "))
    ))

if __name__ == "__main__":
    main()

Stratégie de migration

Ne réécrivez pas tout d'un coup. Migrez station par station :

  1. Choisissez une station de test avec la séquence la plus simple
  2. Documentez la spécification de test existante (étapes, limites, instruments, flux)
  3. Écrivez l'équivalent Python en suivant les patterns ci-dessus
  4. Exécutez les deux systèmes en parallèle pour un lot de production
  5. Comparez les résultats pour vérifier l'équivalence
  6. Basculez quand les résultats correspondent
  7. Passez à la station suivante

Conservez vos séquences LabVIEW TestExec comme documentation de référence. Les scripts Python les remplacent, mais avoir la spécification originale aide pendant la validation.

Pièges courants

ProblèmeSolution
Les pilotes NI nécessitent le runtime LabVIEWPyVISA avec le backend NI-VISA fonctionne sans LabVIEW
Groupes d'étapes parallèles TestExecUtilisez le threading ou asyncio Python
Callbacks TestExec (en cas d'échec, en cas de réussite)Options de phase OpenHTF et callbacks de sortie
Suivi du modèle/numéro de série de la stationPropriétés de configuration de station TofuPilot
Génération de rapports TestExecTofuPilot génère les rapports automatiquement
Boutons de l'interface opérateurInterface station web de TofuPilot ou Tkinter personnalisé

Le plus difficile n'est pas le code. C'est valider que les nouveaux tests détectent les mêmes défaillances que les anciens. Exécutez les deux systèmes en parallèle jusqu'à ce que vous soyez confiant.

Plus de guides

Mettez ce guide en pratique