MyEnigma

とある自律移動システムエンジニアのブログです。#Robotics #Programing #C++ #Python #MATLAB #Vim #Mathematics #Book #Movie #Traveling #Mac #iPhone

ROSにおけるUnit/Integration/Regression Test (日本語訳)


(元のページ:UnitTesting - ROS Wiki http://wiki.ros.org/UnitTesting)

はじめに

本章では、ユニットテストや統合テストを作成し実行するための、

ヒントやポリシーについて説明します。

それぞれのプログラミング言語におけるテストの書き方については、

下記を参照してください。

・C++:gtest http://wiki.ros.org/gtest

・Python: unittest http://wiki.ros.org/unittest

・rostest: rostest http://wiki.ros.org/rostest

なぜユニットテストをしなくてはならないのか?

この問いに関して、もっとも簡潔な答えは

”しなくてはならない”からです。


ユニットテストは下記のリンク先のROSソフトのQAプロセスの

一環として必要なステップです。

QAProcess - ROS Wiki http://wiki.ros.org/QAProcess


もし、ユニットテストをしていない場合、

あなたのコードはリリースやコードレビューをクリアしていないとみなされます。

実際、コードレビューを行う際には、あなたのコードだけでなく、

あなたのユニットテストの内容と結果もレビューされるのです。


ユニットテストはどの品質のプログラムにおいても重要ですが、

それよりも、非常に多くのコンポーネントから構成される

様々なソフトをサポートするために重要となります。


ユニットテストが無ければ、

そのソフトをデバックするのは無理だと言ってもいいでしょう。


ユニットテストには、セットアップするのに時間がかかりますが、

それによりあなたは将来、より多くの時間を節約することができるのです。


ユニットテストを行う利点を下記に記します。

1. より早いペースでコードをインクリメンタルに更新していくことができるようになります。

ROSのコア開発では180以上のパッケージ群を開発しており、

それらは相互に依存しています。

なので、あるソフトを少し修正したことにより、どれだけ大きな問題が生じるのかを

予測することは非常に難しいという問題があります。


しかし、もしそのパッケージがユニットテストを通過したのであれば、

あなたの修正により問題を引き起こしてはいないという自信を持つことができるのです。

(もしくは、最低でも既存の問題はあなたのせいではないことがわかります。)

2. 自信を持ってリファクタリングをすることができるようになります。

ユニットテストを通過させることにより、あなたのリファクタリングの際に、

バグを仕込まなかったということが確認できます。

3. より良い設計がされたコードを作成することができます。

 
ユニットテストをすることにより、あなたは自分のコードを

よりテストがしやすいように書くようになります。

これにより下部の関数とフレームワークを分けることにつながり、

ROSソフトの設計の目標により一層近づくことになります。

4. バグの再発を防ぐことができます。

あなたが直したすべてのバグに対するユニットテストを書いておく習慣は重要です。

以前直したバグ用のユニットテストを使用することにより、

直したバグが再発していないかをチェックすることができるのです。

5. ユニットテストにより、他の人からの意見に反論することができます。

ユニットテストは、あなたのコードが期待されている仕様を満たしていることを示す

文書の一種でもあるのです。

6. 他の人があなたのコードを簡単に利用できるようにします。

他の人のコードを修正した時に、

そのコードが壊れてしまったのかどうかを判断するのは非常に難しいことです。

ユニットテストをすることにより、他の人があなたのコードを変更したときの

確認をすることができるようになります。


テストのレベル

ROSソフトにおけるテストのレベルは下記の3つに分類されます。

1. ライブラリユニットテスト(unittest,gtest)

ライブラリユニットテストは、ROSソフトであるかに関わらず実施すべきです。

(もしテストする時間が非常に多くかかる場合は、

そのライブラリをリファクタリングしたほうがいいと思います。)

あなたのコードにおいて下部の関数がうまく分離され、

境界条件や意図しない入力がされた時のテストをしているのかを

きちんと確認すべきです。

また、あなたの関数の事前条件などはちゃんとテストされているのかは

きちんと確認すべきです。

最後に、そのような様々な条件下におけるあなたのコードの振る舞いに関して

きちんとドキュメント化されているのかを確認すべきです。

2. ROSノードのユニットテスト (rostest + unittest/gtest):

このレベルのノードのユニットテストでは、ノードの立ち上がりと、

外部API(送受信のTopicやService)をテストすべきです。

3. ROSノードの統合/回帰テスト (rostest + unittest/gtest):

統合テストでは複数のノードの立ち上がりや、

それらのノードが期待通りに同期するかをテストします。

ROSのノード群をデバックすることは、

マルチスレッドのコードをデバックすることに似ています。

それらのコードはデットロックをするかもしれませんし、

競合状態を引き起こすかもしれません。

統合テストは、バグを洗い出す最も良い方法の一つなのです。



あなたのコードにとって、上記のテストのどのレベルが必要であるかは、

あなたのコードの内容によります。

下記はテストレベルの具体例です。

1. ROSのフリーライブラリ(数学的な処理などのライブラリ)

これにはレベル1だけで十分でしょう。

2. ROSのサービス


殆どのROSのサービスはレベル1と2のテストで十分です。

レベル2のテストでは、APIを出来るだけ使用し、

下部のスレッドやパフォーマンス問題が無いか

どうかをちゃんと確認しましょう。

3. Publisher/SubscriberであるROSノード

殆どのROSノードは3つのすべてのレベルのテストをすべきです。

レベル1のテストでは下部の関数をテストし、

レベル2のテストではROSレベルの機能を確認し、

レベル3のテストでは競合やデットロック状態が存在するかをテストします。


参考資料

ユニットテストに関しては下記の記事が参考になります。

Chapter 13. Unit Testing http://www.diveintopython.net/unit_testing/index.html

gtest - ROS Wiki http://wiki.ros.org/gtest

unittest - ROS Wiki http://wiki.ros.org/unittest

MyEnigma Supporters

もしこの記事が参考になり、

ブログをサポートしたいと思われた方は、

こちらからよろしくお願いします。

myenigma.hatenablog.com