FirebaseとSendGridで作るメルマガサービスの検証方法

記事
IT・テクノロジー

FirebaseとSendGridで作るメルマガサービスの検証方法

前回はモジュールごとに分けて検証をする事例を、FirebaseとSendGridでメルマガ(ニュースレター)サービスの例を使って説明しました。その中でいろいろな機能がありますが、その一つの機能、メルマガメルマガ(ニュースレター)の送付先の登録の機能についてより具体的な話をお届けしました。
今日はさらに詳しい部分について考えていくことにします。
ところで、プログラミングを勉強して起業や就職に役立てようという方がたくさんいらっしゃるので、プログラムのやり方に関する記事は沢山あります。一方で、作ったプログラミングをどのように検証(テスト)するかという記事はプログラミングのやり方に比べると圧倒的に少なくなります。
前回も触れましたが、実際は、プログラミングを作る(実装する)作業よりも、出来上がったプログラミングを検証する方が、時間も手間もかかります。そして、品質の良いプログラムを提供するには、十分な検証(テスト)をする必要があります。さらに、これも前回触れていますが、プログラムを検証するためのプログラムの開発も必要になることも多く、意外に軽く見られがちな検証(テスト)ですが、プログラムの開発ではなくてはならないステップなのでここでも取り上げることにしました。

プログラムの検証の基本

プログラムの検証の基本は、起こりうることを全てテストするというのが究極のゴールです。 実際は全ての機能の検証はできないか、実行するのが非常に難しい場合も多く、100%のテストというのは現実的にはできない場合がほとんどです。これが「想定外」の動作が起きる理由です。
そこで少しでも、想定外を減らせるように、テストの範囲を絞って行うのが基本的な検証戦略になります。 モジュールに分けて機能を絞ることで、できるだけ全てのケースの検証を行なおうというアプローチです。
今日は前回取り上げたモジュールレベルの検証のうち、ユーザーインターフェースから入力されたデータを受け取ってバックエンドにデータを渡す部分の検証についてさらに詳しく考えてみます。
このモジュールの機能は:
* ユーザーインターフェースから入力されたデータを受け取る
* 受け取ったデータをバックエンドに送付
* バックエンドからの応答に応じた処理を行う
この3点です。
ユーザーインターフェースから受け取るデータは3種類です。
* E-Mailアドレス(必須)
* 苗字(無くても可)
* 名前(無くても可)
バックエンドに送るデータは同じです。
データをバックエンドに送った後はバックエンドからの応答を待って、その結果によって処理を行って終了です。
このモジュールの処理結果は2つです
* 処理の成功
* 処理の失敗(エラー)
この処理結果をユーザーインターフェースに返します。
* 処理が成功した場合は「true」
* 処理が失敗した場合は「false」
を返すようにします。
これらをシンプルにすると、このモジュールへの入力は、ユーザーインターフェースからの入力データで
* E-Mail
* 苗字
* 名前
の情報で、処理結果は、
* 処理の成功(treu)
* 処理の失敗(false)
という事になります。
バックエンドのインターフェースは、受け取った入力データを送って、バックエンドの処理が
* バックエンドの処理が成功(true)
* バックエンドの処理が失敗(false)
という事になります。
あとは、このモジュール内の処理によって検証内容が変わってきます。
* このモジュールで入力データのチェックをするか
あたりがポイントです。前回の解説では「想定外」を避けるために一応入力データをチェックするにしていました。

テスト項目を考えたうえでの設計も大切です

このモジュールで入力データをチェックするかどうかでテスト内容は変わります。
チェックする場合は、「チェックが正しく行われるか」を検証する必要があります。
その場合は、テストに必要な入力データに、チェックでエラーになる場合とエラーにならない場合のデータが必要になります。データをチェックする大きな理由は「想定外」の可能性を減らすのが一番の目的なので、考えるのは「想定外」の可能性を考える必要があります。
もう一つは、アプリ、サービス全体としての「エラー処理」の考え方です。 例えばエラーを何処で見つけるかという事です。
SendGridのメッセージの送付先の登録には「E-Mailアドレス」は必須のデータで、苗字や名前はなくても受け付けてくれます。これが、入力データの制約になっています。そう考えるとエラーを見つける場所は幾つか考えられます。
* ユーザーインターフェースでデータの送信前に見つける
* 今回取り上げている、ユーザーインターフェースから受け取ったデータをバックエンドに送るところで見つける
* バックエンドで見つける
* SendGirdでエラーになるのを利用する
これを考えると、このモジュールで入力するデータをチェックする必要性は少ないことがわかります。
このモジュールはユーザーインターフェースと同じWebブラウザーで動くことになります。従って、ユーザーインターフェースで入力データをチェックしている場合、誤ったデータを受け取る可能性は限りなくゼロに近いという事になります。
一方で、ユーザーインターフェースで入力データをチェックしない場合、誤ったデータは送られる可能性はあります。 しかし、その時点でデータは送られてしまっているわけで、エラーの検出がこのモジュールでもSendGridのサーバーが受け取った後でも多少の時間の違いはありますが、利用者からみると「同じ結果」です。つまり、送信後に、処理のエラーを受け取ってエラーになるという点で同じです。
データを送る前にチェックする意味は大きいですが、利用者の立場で考えると送った後のエラー検出という点では差がありません。そう考えるとこのモジュールでエラーをチェックしない方が、検証もシンプルですし実装もシンプルになります。
ということで、この記事ではこのモジュールでは入力データをチェックしないことにします。

検証項目は?

これで検証項目はかなりシンプルになりました!
* 入力データと同じデータがバックエンドに送信されているか
* バックエンドの応答の処理結果をユーザーインターフェースに転送しているか
この2点だけになります。
では、どんな入力データをこのモジュールに与えれば良いのかというのが次のポイントです。
今回はこのモジュールではデータの中身のチェックはしないで、「横流し」をするだけなので基本的にはデータは数パターンのテストをすれば通常は十分という事になります。

想定外はあるのか?

このモジュールの機能をシンプルにしたので、検証(テスト)はかなり簡単になりました。 では、このモジュールに想定外はあるでしょうか?
これが今日のポイントです!
いずれにしても完全に全てのケースをテストするのは不可能なので結論から言ってしまえば、想定外はありうるという事になります。
まず、最初に言えるのが、全ての入力データはこの場合でも試せません。 入力データの「E-Mail」、「苗字」、「名前」は全て文字列です。従って全てのデータパターンをテストすることはほぼ不可能です。また、テストする意味も殆どの場合はありません。
次が処理系の制限がある可能性があります。これは、扱う事の出来る文字列のサイズは無限ではありません。扱う事ができる文字列のサイズは一定の上限があります。このケースの場合は、ユーザーインターフェースも同じWebブラウザーで動作しているので、こちらで制限を超えている場合このモジュールに渡される前にエラーになる可能性が高いため、入力で問題になる可能性は少ないと思われます。しかし、バックエンドに送る際はネットワークを介すために、ここで制限を超える可能性はあります。その場合、エラーを返すのはSendGridのサーバーでない可能性があるので、これも想定外になりえます。つまりどのようなネットワークインターフェースを使うかで状況は変わります。
もう一つよくある、想定外に「タイムアウト」があります。一定時間たっても応答がかえって来ない場合です。これも、利用するネットワークアクセスのモジュールや、タイムアウトの設定(設計)によって変わってきます。
これらは、事前に想定してれば対策を設計上取ることは可能ですが、想定していない場合、予想できない動作になる場合があります。想定している場合は、対策の検証も可能ですが、想定していない場合はテストも困難です。その場合は、実際の稼働してるときに想定外が発生してしまう可能性があるという事になります。
これだけシンプルなケースでもいくつか見落とし安い想定外があります。これがもう少し複雑な処理になると、さらに増えることになります。

前のモジュールで引き渡すデータをチェックすれば安全か?

今回のこのモジュールでは、ユーザーインターフェースで入力データをチェックしていればほぼ問題なしという判断でしたが、これも条件によって変わってきます。このケースは、基本的に同じWebブラウザーで動くプログラムという事でこのデータが問題になる可能性は低いと考えました。
しかし、バックエンドの場合はどうでしょうか?
これは、話が違ってきます。バックエンドの処理は完全に別のプログラムです。しかも、データはネットワークを経由して送られてきます。この場合は、バックエンドにデータを渡す前にしたチェックは余り意味をなさない可能性も大いにあり得ます。
完全に別の所で動いているプログラムで、開発用の特殊な環境でない場合は、ほとんどの場合別のコンピュータで実行されています。ネットワーク上では転送時のエラーも頻繁に発生するので、受け取ったデータがチェックしたデータとは違う可能性は高くなります。そう考えると、データを改めてバックエンドでチェックする意味も大きくなります。
Webのサービスやアプリはこのように、デスクトップのアプリに比べると仕組みがやや複雑になるので、検証の戦略も複雑になります。そういう意味で、モジュールごとに分割して相互の関係を見ながら検証の戦略をたてるのがとても重要です。

まとめ

WebサービスやWebアプリの場合、複数のプログラムが別のコンピュータで動く場合が多くなります。
まずは、サービスやアプリ全体を見て、モジュール分割をして検証戦略を立てながら実装を検討すると、設計コンセプトも最適化する事ができます。そのうえで、効率的な検証戦略を立てると、検証もある程度シンプルにできます。
現実的には、検証戦略をシンプルにしても、全てのデータパターンをテストできるわけではありません。モジュールに分割することで、個々の部分のテストのカバー範囲を挙げて、積み上げることで、サービスやアプリ全体の検証のカバー範囲を広げていくという戦略が重要になります。
サービス数40万件のスキルマーケット、あなたにぴったりのサービスを探す