ロボット(およびその他の機械装置)の単体テストを作成するにはどうすればよいですか?


22

私は高校のロボットクラブのメンバーであり、ロボットのプログラミングを担当しています。さまざまな大人から聞き続ける提案の1つは、コードを検証するために単体テストを作成する必要があるということです。コードベースは少し大きくなってきており、バグをより迅速に見つけるのにユニットテストが本当に役立つことに同意します。

ただし、これをどのように実現できるかは完全にはわかりません。私の知る限り、ユニットテストは、関数(またはコードのサブシステム)を取得し、それに一連の入力を与えて、毎回同じ出力が得られることを確認することによって行われます。私が現在持っているコードは、大量のデータを処理するのではなく、ロボットのハードウェアコンポーネントを直接操作します。複雑さの大部分は、電子機器が正常であること、現時点のコードがロボットの実際のハードウェアと一致することなどを確認することから生じます。多くの場合、問題を確認できるのはロボット自体にコードをロードすることだけです。そしてそれを実行しようとしています。

拡張により、機械式デバイスを操作するためのコードの単体テストをどのように作成できますか?機械の動作を物理的に観察することによってのみエラーをキャッチできるように思えます。

それとも、単体テストがどのように機能するかを誤解しているだけですか?

それが重要な場合、ここにコードがあります、それはC ++で書かれており、私はFRCに参加しています

回答:


21

このテストを行うには、ハードウェアレイヤーをモックする必要があります。コードは、実際のハードウェアと通信する代わりに、制御可能なハードウェアの偽バージョンと通信し、コードが正しく機能していることを確認するために使用します。

残念ながら、克服しなければならない問題がいくつかあります。

  • 比較的低レベルの言語で物事を模倣することはより困難です(したがって、より多くの作業が必要です)
  • ハードウェアレベルのもののモックはより困難です(したがって、より多くの作業が必要です)

また、自動化された単体テストの価値の大部分は、元のコードを記述した後、長期間にわたって回帰バグをキャッチするためにいつでもテストを実行できることにあります。これらの種類のコンテストでは、コンテスト終了後にコードがまったく使用されないため、テストからほとんどの価値を引き出すことはできません。特定のケースにテストを追加するのがどれほど難しいかを考えると、手動テストを行い、コンテストの機能に焦点を当てる方が時間を有効に活用できる可能性があります。


1
いい答えだ。特に、競合後にコードが使用されないという事実と、テストが記述された後、自動化された単体テストの大きなメリットが得られるという事実についての少し。同じテストを何度も実行している場合は、テストの一部を自動化することを検討してください。しかし、これが起こるまで、あまり意味はありません。
ダウッドは、モニカを復活させると

ハードウェアをモックする必要はまったくありません。ロボットにログが記録されている場合は、テストプログラムを実行してログを確認します。最終テストでは、ログ内の「左折」の観察が必要であり、ロボットが左折するtpoに対応する必要があります。入力デバイスをモックするためのテストハーネスを作成する必要があります-入力デバイスコードをハードウェアレイヤーのできるだけ近くにフックします
-mattnz

4
@DavidWallace TDD / BDDを使用すると、単体テストのメリットがすぐに得られます。第一に、コードを即座に自信を持ってリファクタリングできるようにすること、そして第二に、実装がテストを満たすために必要な最小限の実装に制限されるようにすることです。
-S.ロビンズ

4
@mattnzの悪いアイデア、そして私は経験から知っています。テスト対象のコードが非常に激しく失敗し、ロボットアームが壁に衝突してxxxx $のハードウェアを破壊した場合はどうなりますか?
stijn

2
@mattnz:私たちのロボットは約2フィートx 3フィートx 4フィートで、重量は約150ポンドです。キット/登録には毎年5,000ドルの費用がかかり、通常、追加の部品を購入するためにさらに5〜10kを募金します。最悪の場合のシナリオでは、おそらく10ドル以上かかります;)
Michael0x2a

10

私はあなたが考慮する必要があるいくつかのことを考えることができます。最初の方法は、ハードウェアアクセスレイヤーをできる限り薄くすることです。これは、基本的なラッパータイプのレイヤーを作成することを意味します。これにはいくつかの利点があります。1つ目は、ハードウェアアクセス自体からコードのハードウェア固有の動作を分離できることです。つまり、ハードウェア自体にアクセスする必要なく、ハードウェアcommsの一番下まですべてをテストできます。

たとえば、I2Cベースのシグナリングプロトコルを設計する必要がある場合、テストでハードウェアをフックすることなく、コードが正しいI2C信号を生成していることをテストできます。

実際のハードウェアへの呼び出しについては、ハードウェアレイヤーをモックすることで正しく動作していることをテストできます。これは、非常に薄いハードウェアレイヤーを維持することが実を結ぶ場所です。実際にハードウェアに対処しますが、すべてのシグナリングはより高いレベルでテスト可能である必要があるため、必ずしも個々の信号自体をテストする必要はありません。つまり、モックを使用して、信号がハードウェアに送信される特定のハードウェアメソッドが呼び出されていることを確認します。ハードウェアをポーリングする必要がある場合、モックはコード内のイベントまたはメソッドのみをトリガーできる必要があります。これも、リターンシグナルは上位レイヤーで処理される必要があるためです。

これは基本的に、Oleksiが彼の答えで言ったことに適合します。ハードウェアレベルのものをモックするのは通常より多くの仕事ですが、可能な限り最小限のコード/コールレイヤーを維持することはそれほど難しくありませんハードウェア。

すべてのテストに合格するコードがある場合でも、ハードウェアレイヤーですべてを正しく起動させるために、一連の手動テストを実行する必要があります。

モックと階層化とは別に、頭に浮かぶもう1つのことは、テストファーストの開発手法を使用することです。基本的に、要件をテスト基準としてコーディングし、テストに基づいて実装を行います。これにより、実装コードを最小限に抑えながら、すべてのテストケースで開発作業を推進できます。「理由」を実行するように誘惑される可能性のある他の潜在的に重要でないコードに時間を無駄にしないことで、最初にテストすることで集中力を維持し、デバッグ中にコードを簡単に変更できるようになります。単体テストとモックの。ハードウェアを介してソフトウェアのバグをデバッグすることは、悪名高いほど複雑であり、他のタスクに費やす時間を大幅に浪費します。


2

Flight Simulatorでどのように機能するかを説明できます。

まず、プログラマーだけにこの質問をした場合、半分の答えしか得られないので、たぶんhttp://electronics.stackexchange.comにクロスポストする必要があります。

私はロボットを使って仕事をしたことはありませんが、フライトシミュレータでハードウェアを5年間使って、ロボットのアーキテクチャがどのように機能するかを説明しました。

ハードウェアレイヤーがダム

シンプルな入力/出力値を調整し、アナログ信号の補間ブレークポイントを設定できる基本的なインターフェイスが含まれています。「新鮮な」ハードウェアを使用している場合、ほとんどまたはまったくキャリブレーションを行わなくてもすべてが期待どおりに機能しますが、時間が経つにつれて部品は機械的な摩耗を受け、調整する必要があります。

キャリブレーションは、最小値と最大値の間の範囲に区分されたシンプルなテーブルです。これらの入力を測定するために、通常、サーボが使用されます(リニアポテンショメータ、トランスデューサ、加速度計など)。または、計装の場合は、正確さを視覚的に判断し、較正されるまで調整するだけです。

ソフトウェア層は反対です

すべてが複雑で相互接続されているため、いくつかの変数を分離して機能をテストすることが重要です。データを収集できる現実的なシナリオを実行する方がはるかに簡単であるため、シナリオを考えて頭を悩ます必要はありません。テストを実行すると、基本的に現在の出力に対して保存されたデータを測定します。

フライトシミュレータでは、これはQTG(Qualification Test Guide)と呼ばれます。そのコアでは、1つの次元が時間で、もう1つの次元が出力である2Dグリッドにデータをプロットします。

信じられないかもしれませんが、それがモデルの開発方法の本質です。実際の飛行機には大量のセンサーが装備され、制御されたシナリオを実行します。すべてのコントロールは人の介入なしに駆動できるため、テストはコンピューターによって実行され(つまり、シミュレーション自体が実行され)、データが比較されます。

ロボット工学は非常に異なる規模で作成されていますが、原理は同じです。従来のアプローチでは、ハードウェア層とソフトウェア層を完全に切断して、両方を個別にテストできます。ハードウェア入力はサーボを介して収集され、独立したインターフェースを介して設定されます。ソフトウェア入力は、ハードウェアに送信される信号を個別に測定および比較し、既知の「良好な」データに対してプロットすることにより、設定/読み取りできます。

テスト自体は、結果が予測可能で、測定可能で、再現可能である限り、必ずしも複雑である必要はありません。


1

前に述べたように、ハードウェア部品のモックとスタブを作成します。たとえば、ロボットへのインターフェイスがある場合は、そのインターフェイスから継承して、それを簡単にスタブ実装できます。その後、スタブ実装が期待どおりに呼び出されたことをテストできます。それが期待される機能または期待されるパラメータである場合。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.