テストで活躍するNode-RED

Node-REDはテストに使うととても便利です。使わない手はありません。
Node-REDはデバイス制御や通信のモジュールが豊富で、IoTシステムなどデータ連携が必要なシステムの開発に用いられています。生産性が高く、デバッグやテストに便利なUIを持ち、プロトタイピングにも適しています。
開発をしていると連携するシステムがまだできていないことがあります。仕方がないのでスマホアプリ代わりのドライバや共通処理のモック、すでに共通処理があるなら機器のスタブなど必要に応じていわゆるテストダブルを作ることになります。
テストダブルを作ってみると、Node-REDなら色々な機能の作成が簡単にできることがわかります。ここではNode-REDをどのように使うとテストを効率化できるか、経験を踏まえて説明します。

#TL;DR
* お手軽にテストダブル作成
    * クライアント（ドライバ）にもサーバー（モック／スタブ）にもなれる
    * JSONでお手軽にパラメータを変更
* 結合テストの自動化
    * ドライバとモック／スタブを組み合わせてテスト
    * クラウドとの連携もバッチリ
* 汎用ツールとして本格的に使う
    * シミュレータもUI付きで作れる
    * 負荷試験も得意

#お手軽にテストダブル作成

単純なモックやドライバは3ノードからできます。[Hello World!からNode-REDを知る](http://sakaba.cocolog-nifty.com/sakaba/2016/04/node-red-hello-.html)の例はサーバーのモックの一例と言えます。httpのGETに対して「Hello World!」を返しています。
Node-REDのプログラムは、この例のように、入力/起動、処理、応答/デバッグの3つのノードで実現できます。このp例では応答だけでなくデバッグ出力もあるので4つになっていますが、基本は3つのノードでできます。ここで入力のhttp inノードをダブルクリックして設定画面をだすと、GETでなくPOSTを選んだり、URLや受け取るパスパラメータなどを指定できます。処理はペイロードの指定だけでなく、ファンクションノードで複雑な処理を書いて、応答内容やステータスコードを指定することもできます。
このフローはhttp inノードで始まっていますが、インジェクトノードから始めてhttp requestノードにつなぐとAPIの呼び出しを行うことができます。後段にデバッグノードをつなげが結果を表示できますし、switchノードでチェックすることもできます。http requestでも入力されたデータを受け渡しするだけでなく、クライアント証明書など各種設定ができます。

APIで受け渡しをするデータがJSON形式の場合も多いでしょう。そんな時はテンプレートノードが便利です。ビジュアルなJSONエディタで入力でき、エラーがあれば指摘してくれます。テストをするはずなのにテストデータのデバッグで時間がかかるということも少なくなります。
大きな配列などでプログラムでセットしたい場合は、ファンクションノードを使えばjavascriptのプログラムを書いてセットすることもできます。

#結合テストの自動化
結合テストでスマホアプリ代わりのドライバと、バックエンドや機器代わりのモックあるいはスタブを組み合わせてテストする場合、Node-REDのコンテキストオブジェクトと呼ばれる広域データ（参考：[Node-REDにおけるコンテキストの活用について](https://qiita.com/utaani/items/4f9b12f2ee6b1c5a620f)）が便利です。コンテキストオブジェクトにはプログラムのどこからでも利用できるグローバルオブジェクトと、画面エディタのタブで区切られる範囲で利用できるフローオブジェクトがあり、エディタ画面で実行中のデータを管理できます。コンテキストデータをつかえば、ドライバとモックあるいはスタブで連携したテストケースを簡単に実現できます。さらに、個々のテストケースを実現したあと、それぞれをつなげて連続実行することもできます。

Node-REDはテスト対象に限らずAPIの呼び出しが簡単です。クラウドとの連携も簡単ですので、テスト用にデータをセットしておいたり、結果のデータやログを取得することができます。取得したデータのチェックや保存もできますので、各テストケースで応答以外のデータを含めてテスト結果を確認し、エビデンスを残すことができます。
テストの規模が大きくなるとどこまで実行できたかが気になるところです。デバッグノードやディレイノードなどのステータスは、ノードの下にビジュアルに表示されますので、テスト中にずっとログを常に監視しなくても良くなります（参考：[ファンクションノードのデバッグどうしてる？](http://sakaba.cocolog-nifty.com/sakaba/2019/12/post-e83964.html)）。

#汎用ツールとして本格的に使う
モックでテストしていると、汎用的に作り直したほうが便利に思うことがあります。このような場合は、実際の機器のようにプロパティ（状態）を持たせて、要求に応じて処理を変えるスタブを実現します。
スタブ化すると徐々に欲が出てきます。スタブのログをファイルやログに残しておいて、[ダッシュボード](https://flows.nodered.org/node/node-red-dashboard)のUIを使ってEXEC ノードからAWKで検索して様々な条件で表示することができます（時刻の範囲で検索しやすいのでAWKを使います）。ダッシュボードはグラフィカルなUIが有名ですが、単純なボタンやドロップダウンメニュー、テキスト入力、テンプレートノードなどがテストには便利です。ログ検索も簡単になります。
ダッシュボードを知ると、テスト用にイベントを送りたくなります。ボタンを押して機器からのイベントを送るのです。ここまでくると、スタブというよりもシミュレータと言えるでしょう。Node-REDではクラウド環境のほか、NeDBなどNode.jsで利用可能な多くのライブラリが使えますので、必要に応じてどんどん機能アップすることができます。

Node-REDで試験をしていると、負荷試験もやりたくなります。
Node-REDはNode.js上で動いていますので、負荷試験に向いています。通常の言語だと複数機器のシミュレーションをする場合はスレッドで実行すると思いますが、スレッド数を増やすと徐々に処理数倍以上に遅くなります。これに対してNode-RED（Node.js）は非同期処理なので、単純に処理数倍に遅くなります。例えば軽量な通信で繋がれた10msecの処理を1秒以内に終えればよいのであれば大体100台シミュレーションできることになります。1台分のシミュレータのプロパティを配列にすれば比較的簡単に複数台対応できますし、コンテナやクラウドと組み合わせれば、1万台単位の負荷試験も比較的安価に実施できます。
#おわりに
使ってみるとその良さがすぐにわかるNode-REDですが、IoT関係以外ではまだそれほど知られていません。私の使い始めたきっかけもIoTに関係する仕事でしたが、Node-REDの汎用性、生産性、[保守性](https://qiita.com/utaani/items/4f9b12f2ee6b1c5a620f)を知るとテストに使わない手はありません。興味を持たれた方はぜひ挑戦してください。おすすめです。