TestStandでテストプログラムを作成する場合、テストの中心的機能は個別のコードモジュールに実装されます。TestStandには、LabVIEW、LabWindows™/CVI™、C#、VB .NET、C/C++、ActiveXなど、さまざまなプログラミング環境および言語を使用して開発されたコードモジュールを呼び出すアダプタが用意されています。
このドキュメントでは、テストシステムのコードモジュールを開発し、テストシーケンスからそれらを呼び出すときに考慮すべきベストプラクティスについて説明します。このドキュメントを使用するには、基本的なテストシーケンスの作成方法など、TestStandの操作に関する基本的知識があることが前提となります。これらの概念に慣れていない場合は、このドキュメントを使用する前に、以下の入門リソースを参照してください。
コードモジュールの実装方法の詳細については、TestStandヘルプトピック「標準ステップタイプ」と「モジュールアダプター」を参照してください。
テストシステムの開発を開始する前に、テストシステムの次の側面に対する一般的なアプローチを策定することを検討してください。
テストシステムを設計するときは、コードモジュールに一貫したレベルの粒度を定義することが重要です。 粒度とは、テストシステムの各コードモジュールの機能のスコープを指します。 粒度の低いテストシーケンスがそれぞれがより多くの機能を実行する少数のコードモジュールを呼び出すのに対し、粒度の高いシーケンスはそれぞれがより小さなスコープを持つ多数のコードモジュールを呼び出します。
粒度が低い | 粒度が高い |
|
|
それぞれに独自の長所があるため、両者の間でバランスを取る必要があります。
さまざまなレベルの粒度を使用して簡単なテストを実装する
テストシステム全体で一貫した粒度を維持するには、次のようなコードモジュール開発の一連の標準を作成します。
テストステップでコードモジュールのパスを指定する場合、絶対パスと相対パスのどちらを使用するかを選択できます。次の理由により、絶対パスの使用はお勧めしません。
相対パスを指定した場合、TestStandでは検索ディレクトリのリストを使用してパスを解決します。 これらの検索ディレクトリには通常、現在のシーケンスファイルディレクトリ、TestStand固有のディレクトリ、およびシステムディレクトリが含まれます。
開発を始める前に、テストシーケンスとコードモジュールのファイル構造を定義することが重要です。 以下のガイドラインを使用して、シーケンスファイルとコードモジュールを格納する場所を定義します。
コードモジュールをシーケンスファイルのサブディレクトリに配置するディレクトリ構造の定義
TestStandデプロイメントユーティリティを使用してテストコードをデプロイする場合、シーケンスファイルと依存コードモジュールに対して特定のデプロイ先を選択できます。 シーケンスファイルのデプロイ先ディレクトリとコードモジュールのデプロイ先ディレクトリの間に相対パスが存在する場合、TestStandデプロイメントユーティリティは、更新された場所を指すようにシーケンスファイル内のパスを更新します。 一般に、デプロイメントのディレクトリ構造を開発システムのディレクトリ構造と一致させて、デプロイメントが開発マシン上のコードにできるだけ類似するようにすることをお勧めします。
テストシステムのコードモジュールのスコープを定義する場合、どの機能をコードモジュールに実装し、どの機能をシーケンスファイルに実装するかについて方針を決めることが重要です。以下のセクションをお読みいただくと、よく使用する機能を実装するのに最も適した場所を決定することができます。
コードモジュールにはテスト計測値の取得に直接関連する機能を含め、テストシーケンスで未処理のテスト結果を処理することをお勧めします。このアプローチには以下の利点があります。
より単純な計測の場合、コードモジュールは未処理の計測値を処理のためにシーケンスに返すことができます。たとえば、テストステップで被試験装置(UUT)の特定のピンの電圧を計測する場合、コードモジュールは、それ自体で直接チェックを実行するのではなく、計測された値を返す必要があります。 この値を制限数値テストステップで処理して、シーケンスファイルのテスト結果が制限値を超えていないかどうかを判断できます。
テストステップで制限値からの逸脱を評価すると、コードモジュールが簡素化され、結果のロギングが改善される
ただし、複雑なテストもあるため、未処理のテスト結果をシーケンスファイルで常に処理できるとは限りません。 より複雑な計測の場合は、結果データの追加処理が必要になる可能性があります。 複雑なデータを処理して単一の文字列または数値結果にすることで、文字列または数値比較を使用してTestStandで評価できます。 たとえば、周波数スイープテストの結果は複雑で直接評価できませんが、データを処理して最小値を表す単一の数値にすることができます。 この場合、コードモジュールは処理された結果を評価し、以下のモバイルデバイステストの例に示すように、ロギング用に周波数データを別のパラメータで返す必要があります。
より複雑なデータの場合は、コードモジュールでデータを処理して数値または文字列の結果を生成し、パラメータで未処理データを渡して記録する
非常に大きい未処理データをTestStandに渡すと、パフォーマンスに大きな影響を与える可能性があります。 このような場合は、TDMSファイルに直接データを記録し、テストレポートからそのファイルにリンクすることを検討してください。 これにより、データは、TestStandに渡さなくても、レポートから参照できるようになります。 このアプローチの詳細については、Including Hyperlinks in a Report - TDMS Fileを参照してください。
ステップがテストステップで使用可能な評価のタイプを使用してテスト結果を評価できない場合は、必要なテストタイプを処理する追加機能を備えた新しいステップタイプの作成を検討してください。 カスタムステップタイプの作成の詳細については、このシリーズの記事Best Practices for Custom Step Type Developmentを参照してください。
多くのテストでは、テストを実行する前に、UUTまたはテスト環境を特定の状態にする必要があります。 たとえば、温度計測を行うために励起電圧が必要だったり、加熱されたチャンバを指定された温度に設定することが必要だったりします。 このようなタイプのモジュールでは、パラメータを使用して、励起電圧や目的の温度などの入力値を渡します。 これには、前のセクションで説明したように、コード内で制限値を直接処理するのでなくテストコードモジュールで未処理データを返すことと同じ利点があります。
TestStandには、テストステップの結果を使用したレポート生成とデータベースロギングの機能が組み込まれています。このため、どのようなタイプのデータロギングもコードモジュール内に直接実装することは避けてください。 代わりに、記録するデータを必ずパラメータとして渡したうえで、TestStandを使用してデータを記録してください。 テスト結果、制限値、エラー情報など、いくつかのデータは、自動的に記録されます。 その他のデータを記録するには、追加の結果機能を使用して、レポートに含める追加のパラメータを指定します。
テストレポートへの結果の追加の詳細については、TestStandに付属している例Adding Custom Data to a Reportを参照してください。
ロギングに関する特定の要件がある場合は、結果処理プラグインを変更または作成することを検討してください。それにより、組込のTestStand結果収集機能を使用して結果を収集し、結果の処理方法と表示方法を決定できるようになります。詳細については、ドキュメントBest Practices for TestStand Process Model Development and Customizationのセクション「Creating Plug-ins」を参照してください。
ループを実装する方法にはそれぞれの利点と欠点があるため、最良の方法を決定するのは困難な場合があります。以下のガイドラインを使用して、アプリケーションに最適な方法を決定してください。
コードモジュール内での内部ループ
シーケンスファイル内での外部ループ
多くのテストシステムでは、スイッチを利用して、単一のハードウェアで複数のサイトをテストできます。 スイッチを使用すると、被試験装置(UUT)のどのピンが事前に定義された経路を通じて特定のハードウェアに接続されるかをプログラムで制御できます。
TestStandコードモジュールにスイッチを実装するには、次の方法があります。
NIスイッチハードウェアを使用する場合は、NI Switch Executiveを使用して経路をすばやく定義できます。NI Switch Executiveへのアクセス権がある場合、一般的に、組込のステップ設定を使用してスイッチングを行うのが最良の方法であり、以下の利点があります。
NI Switch Executiveを使用してTestStandステップ設定 (現在のループ指標またはその他のプロパティを使用して経路を動的に設定するTestStandの式のサポートを含む) から直接経路を指定する
単純なタスクのためにコードモジュールを維持することを避けるために、TestStandの式言語を使用して、基本的な計算と1次元配列操作を実行できます。コードモジュールには、高度なプログラミング要件を実装する必要があります。プログラミング言語では、複雑なタスクに適した強力な機能を提供できるためです。 たとえば、多次元配列の連結は、式言語を使用するよりも、ネイティブのLabVIEW配列連結追加関数を使用する方がはるかに簡単に行うことができます。
場合によっては、.NETフレームワークで提供されるネイティブクラスを使用することで、過度に複雑な式を作成せずに済みます。 たとえば、System.IO.Pathクラスを使用すれば、コードモジュールを作成せずにパス操作を素早く実行できます。
.NETステップを使用すると、コードモジュールなしで.NET Frameworkのメソッドを利用できる
コードモジュールを実装する場合、作成するコードモジュールの大部分に影響する設計上の決定事項が多数あります。 このセクションでは、以下の概念のガイドラインについて説明します。
コードモジュール内からTestStandデータにアクセスするには、以下の2つの方法があります。
以下の理由により、一般に、データには、TestStand APIでアクセスするのでなく、パラメータを使用して直接アクセスすることをお勧めします。
必要なデータをコードモジュールに渡すには、できるだけパラメータを使用する
ただし、APIを使用したプロパティへの直接アクセスは、コードモジュールがステップの状態に基づいてさまざまなデータに動的にアクセスする場合に役立ちます。 そのような場合にステップパラメータを使用すると、パラメータのリストが長くなりますが、実際には各種の条件によって一部のパラメータのみが使用されます。
コードモジュール内でTestStand APIを使用するには、SequenceContextオブジェクト(ThisContext)へのリファレンスをパラメータとして渡します。SequenceContextオブジェクトにより、TestStandエンジンや現在のRunstateなど、他のすべてのTestStandオブジェクトにアクセスできるようになります。シーケンスコンテキストへのリファレンスは、終了モニタまたはモーダルダイアログのVIを使用する場合にも必要です。
SequenceContextを使用して、コードモジュール内からTestStand APIにアクセスできる。さらに、TestStand APIを使用すると、プログラムでデータにアクセスできる
TestStandの外部でコードモジュールを再利用する場合、TestStand APIを使用するすべての操作は、モジュールがTestStandシーケンスから呼び出された場合にのみ使用できることに注意してください。モジュールがAPIを介してTestStandから取得したデータは使用できません。 コードモジュールがTestStandの外部で呼び出された場合は、最初にシーケンスコンテキストへのリファレンスがNULLかどうかをチェックすることにより、テストデータを取得するための代替メカニズムを定義できます。 LabVIEWでは、非数/無効パス/非Refnum?関数を使用できます。この関数は、図3に示すようにブール値を返します。
非数/無効パス/非Refnum?を使用すると、TestStandの外部で使用されるコードモジュールのSequenceContextオブジェクトへのリファレンスの有効性をチェックできる
多くの場合、コードモジュールは計測または解析によって大量の複雑なデータを生成できます。 TestStandはデータを保存する際にデータのコピーを作成するため、このようなデータをTestStand変数に保存しないでください。 これらのコピーにより、実行時のパフォーマンスが低下したり、メモリ不足エラーが発生したりする可能性があります。 不要なコピーを作成せずに大きなデータセットを管理する方法は、次のとおりです。
ユーザが終了ボタンを押すと、TestStandは実行中のシーケンスを停止し、Cleanupステップを実行します。ただし、実行によってコードモジュールが呼び出されている場合、シーケンスを終了するには、モジュールが実行を完了して制御をTestStandに戻している必要があります。コードモジュールの実行時間が数秒より長い場合や、モジュールがユーザ入力などの条件の発生を待機している場合、終了コマンドが無視されたように見えることがあります。
この問題に対処するには、終了モニタを使用して、コードモジュールが呼び出し元の実行の終了ステータスをチェックして応答できるようにします。たとえば、付属サンプルのComputer Motherboard Testでは、以下に示すように、シミュレーションダイアログの終了モニタを使用しています。 テストシーケンスが終了すると、「終了状態を確認」VIはFALSEを返し、ループが停止します。
終了モニタの使用方法の詳細については、終了モニタの例を参照してください。
テストシステムのエラーは、テストの実行を妨げる予期しないランタイム動作です。コードモジュールによってエラーが発生した場合は、その情報をテストシーケンスに戻して、実行の終了、前回のテストの再実行、テストオペレータへのプロンプト表示など、次に実行するアクションを決定させます。
コードモジュールからのエラー情報をTestStandに提供するには、以下に示すように、ステップのResult.Errorコンテナを使用します。 TestStandは、各ステップ後にこのプロパティを自動的にチェックして、エラーが発生したかどうかを判断します。 TestStandからコードモジュールにエラー情報を渡す必要はありません。コードモジュールがTestStandにエラーを返す場合、Cleanupステップグループなど、テストシーケンスの別の部分に実行を分岐させることもできます。
ステーションオプションの実行(Execution)タブにあるランタイムエラー設定を使用して、TestStandがステップエラーに応答する方法を設定できます。 通常、デバッグを支援するシーケンスを開発する場合、ダイアログボックスを表示オプションを使用する必要があります。このオプションを使用すると、実行を中断してシーケンスの現在の状態をチェックできるためです。 デプロイされたシステムでは、テストオペレータに対して入力を要求するのではなく、クリーンアップを実行オプションまたは無視オプションを使用することを検討してください。 エラー情報はテスト結果に自動的に記録されるので、テスト結果を使用してエラーの原因を特定できます。
ステップエラーが発生したことをTestStandに通知するStep.Result.Errorコンテナにエラー情報を渡す
デフォルトでは、シーケンスファイル内のシーケンスを実行すると、ファイル内のすべてのコードモジュールがメモリにロードされ、ユーザがシーケンスファイルを閉じるまでロードされたままになります。 この設定では、モジュールのロード中にシーケンスを開始すると、初期遅延が発生する場合があります。 ただし、モジュールがメモリに残っているため、シーケンスファイルの後続の実行はより高速になります。
Step SettingsペインのRun Optionsタブで、コードモジュールをロードおよびアンロードするタイミングを設定できます。通常、デフォルトのロードオプションで最適なパフォーマンスが得られますが、動的にロード(Load dynamically)のロードオプションでコードモジュールを使用している場合にのみ、コードモジュールをロードした方が良いこともあります。 通常の実行では呼び出されないコードモジュール(例: 特定のテストが失敗した後にのみ実行される診断)は、ほとんどの場合まったくロードする必要がないため、動的にロードする必要があります。
コードモジュールを動的にロードする場合、TestStandはコードモジュールをロードする(通常長い実行が終わるころ)までコードモジュールの問題を報告しないことに注意してください。ただし、シーケンスアナライザを使用して、実行前にシーケンスにエラーがないことを確認することもできます。 アナライザは、静的に読み込まれたコードモジュールと動的に読み込まれたコードモジュールの両方をチェックします。
メモリを大量に消費するコードモジュールの場合、デフォルトのアンロードオプションを変更して、メモリの総使用量を減らすことができます。 たとえば、モジュールをステップの実行後にアンロードまたはシーケンスの実行後にアンロードに設定します。 ただし、この変更により実行時間が長くなります。後続の呼び出しごとにモジュールをリロードする必要が生じるためです。可能であれば、64ビットバージョンのTestStandと、より多くの物理メモリを搭載したシステムを使用して、高いメモリ使用量要件にもかかわらず最速のテストパフォーマンスを得られる代替策をお進めします。
コードモジュールが静的変数やLabVIEW関数のグローバル変数などの共有データを保持している場合、アンロードオプションを変更すると、動作が変化する可能性があります。これは、モジュールがアンロードされるとグローバルデータが失われるためです。アンロードオプションを変更するときは、データの損失を防ぐために、必要なデータをTestStandシーケンスに渡すか、より永続的な場所に保存してください。
テストシステムのパフォーマンスを最適化するその他の方法について詳しくは、Best Practices for Improving NI TestStand System Performanceを参照してください。
コードモジュールの一般的な用途は、テストハードウェアと通信し、刺激を設定してテスト計測を行うことです。 ハードウェアとの通信方法には、以下のようなものがあります。
• NI-DAQmxなどのハードウェアドライバを使用して、ハードウェアと直接通信する。
• 計測器ドライバを使用する。VISAまたはIVIハードウェアドライバを介してコマンドが計測器に内部的に送信されます。
使用する通信方法は、お使いのハードウェアのタイプによって異なります。 どちらのタイプの通信でも、ドライバ固有の呼び出しを行う前にドライバへのリファレンスまたはセッションを開き、通信が完了したらハンドルを閉じます。
通常、複数のテストステップで同じハードウェアと通信します。各コードモジュールで計測器セッションを開いたり閉じたりすることによるパフォーマンスへの影響を回避するには、テストシーケンス内でどのようにハードウェアリファレンスを管理するかについて検討する必要があります。 ハードウェアリファレンスを管理するには、2つの一般的な方法があります。
計測器ドライバを使用する場合、あるいはVISAまたはIVIドライバを使用して計測器と直接通信する場合は、ハードウェアセッションの持続時間を直接管理する必要がない限り、セッションマネージャを使用します。 DAQmxなどのハードウェアドライバを使用する場合は、セッションマネージャを使用することはできず、リファレンスを手動で管理する必要があります。
計測器を初期化する際に、セッションリファレンスを出力パラメータとして呼び出しシーケンスに渡し、リファレンスを変数に格納します。 これにより、計測器へのアクセスを必要とする各ステップへの入力として、その変数を渡すことができます。
NI-DAQmx、VISA、およびほとんどの計測器ドライバを含む多くのドライバは、I/Oリファレンスデータタイプを使用してセッションリファレンスを保存します。このリファレンスを保存するには、TestStandでLabviewIOControlデータタイプを使用します。
LabVIEWIOControlタイプの変数を使用して、コードモジュール間でDAQタスクリファレンスなどのハードウェアリファレンスを受け渡しする
TestStandとコードモジュール間で明示的に計測器ハンドルを受け渡す場合は、ハードウェアリファレンスをローカル変数に格納します。 ハードウェアが複数のシーケンスで使用されている場合は、そのハードウェアを必要とする各シーケンスにハンドルをシーケンスパラメータとして渡します。 リファレンスを使用する前に計測器が初期化されているのを確認することが困難な場合があるため、ハードウェアリファレンスを格納するためにグローバル変数を使用しないでください。
以下の理由により、ハードウェアを初期化するにはSetupステップグループを使用し、ハードウェアリファレンスを閉じるにはCleanupステップグループを使用します。
ハードウェアリファレンスを初期化して閉じるには、SetupおよびCleanupグループを使用する
VISAおよびIVI計測器ハンドルの場合、セッションマネージャを使用してハードウェアリファレンスを自動で管理できます。セッションマネージャを使用すると、以下のような多くの利点があります。
セッションマネージャは、セッションの作成後にハンドルを自動的に初期化し、セッションへの最後のリファレンスが解放されると、ハンドルを自動的に閉じます。コードモジュールとシーケンスは、「DMM1」などの論理名を渡すことで、対応する計測器ハンドルが含まれるセッションオブジェクトをセッションマネージャから取得します。
セッションマネージャを使用する場合、セッションオブジェクトをTestStandオブジェクトリファレンス変数に格納します。 セッションの持続時間はオブジェクトリファレンス変数の持続時間にリンクしているため、同じセッションにアクセスするシーケンスコードモジュールとサブシーケンスの数に関係なく、計測器ハンドルは実行ごとに1回ずつ初期化されて閉じます。
下記の例では、Get DMM Sessionステップは、論理名のDMMの計測器セッションオブジェクトへのリファレンスを取得しています。このステップはセッションへのリファレンスをローカル変数に格納するため、シーケンスの実行中に、セッションが初期化されたままになります。
セッションマネージャを使用すると、論理名を使用して計測器を参照できる。 セッションマネージャVIは、論理名を使用してDMM IOリファレンスを取得する
セッションマネージャの使用方法の詳細については、<Program Files>\National Instruments\Shared\Session ManagerにあるNIセッションマネージャヘルプを参照してください。
前のシーケンス例は、別のプロセスでVIを実行するようにLabVIEWアダプタを構成しているため、セッションマネージャを直接呼び出すことによってではなく、セッションマネージャを呼び出すLabVIEWコードモジュールからセッションを取得しています。 セッションマネージャの使用方法の詳細については、<Program Files>\National Instruments\Shared\Session ManagerにあるNIセッションマネージャヘルプを参照してください。
ドライバライブラリを使用すれば、どのようなタイプのハードウェアとも通信できます。ドライバライブラリには、プログラミング言語を使用して一連のタスクを実行できるように設計された機能の一式が用意されているためです。 ドライバライブラリを使用する場合、計測の実行やトリガの設定など、単一の論理操作を実行するために、複数のVIまたは関数を呼び出すことがよくあります。 TestStandステップから直接ライブラリ関数を呼び出すのではなく、その機能を実装するコードモジュールを作成すると、以下のような利点があります。