testingことはじめ(3)〜アプリケーションのテスト〜Golangこんにちは。パッケージを使ったユニットテストについてお伝えしてきました。httptest)今回はGolangで作成したアプリケーションをテストする際に利用できるライブラリなどについて紹介します。ありますので、実際に動作させることが可能です。依存パッケージのダウンロードなお、文章中のコマンドは全てバージョン1.9.2での動作を確認しています。アプリケーションのテストアプリケーションをテストする場合はいくらかのテクニックが必要になります。ここでは、モックを使ったテストやウェブアプリケーションのrouting(エンドポイント)のテストについてGolangでの書き方について記述します。モック通常、ある程度の大きさ以上のアプリケーションを作成する場合、複数のパッケージに分けて分割します。分割したアプリケーションのそれぞれのコードをテストする場合、モックを利用して外部(テスト対象以外)の依存を減らすことが望ましいです。フレームワークと組み合わせて利用することができます。静的なモック用のソースコードを作成します。インストールできます。Golangはツールの配布・利用も簡単です。github.com/golang/mock/mockgenモックの作成モックはインタフェースに対して作成します。インタフェースが含まれているので、これに対してモックを生成します。apple.cultivar}mockgenコマンドを実行します。-sourceオプションでインタフェースが含まれるソース、-destinationオプションで出力先を指定します。接頭辞をつけたものになります。オプションで変更することができます。確認することができます。引数にした以下の関数に対してテストを記述します。food.Name())}モックインスタンスは以下のように作成します。引数で戻り値を指定することができます。}}上記の例でduck.Eat(food)では、FoodのName()を呼び出します。モックを作成して特定の文字列を返却するように指定しているのでテスト実行時の依存を減らすことができます。例では引数は必要ありませんでした。戻り値を設定したい関数に引数が必要な場合は、呼び出される際の引数を指定して限定できます。string}というインタフェースを想定します。モックを利用する場合は以下のようになります。hogeMock.EXPECT().Foo(gomock.Any()).Return("bar")フラグのテストコマンドライン引数やオプションなど、クライアントツールやサーバーアプリを作成した場合にフラグを利用することはよくあると思います。フラグによって動作を変更する場合のテストを想定します。とエラーになってしまいます。そこで、フラグを設定する場合flag.Parse()は利用せずflag.NewFlagSet()で生成されたインスタンスを利用することで、テスタブルなコードを記述することができます。フラグをパースする関数は以下のようにしました。*optC}上記の関数は以下のように利用することができます。optC)}関数ParseFlagをテストするコードは以下のようにしました。0.013s異なる値でフラグのパースを複数回行なっていますが、エラーにならず実行できています。Webアプリケーションのroutingをテストするウェブアプリケーションを開発する場合は、実際にエンドポイントへアクセスして正しい結果が返ってくるかテストすることがあります。アプリケーションを起動してテストする利用するフレームワークがhttp.Handlerの実装となっている場合は後述のhttptestが利用できるので、そちらを利用した方がよいです。ここでは、実際にアプリを起動してhttpクライアントからリクエストを投げ、ハンドラーの想定通りのメソッドが実行されているかどうかを確認します。このサンプルではEchoフレームワークを利用しています。ランダムで空いてるポートをListen多くのウェブフレームワークではサーバー起動時にポートを指定しますが、指定したポートが利用されていた場合はテストが実行できません。以下の関数はランダムで空いてるポートを取得します。以下のソースコードについてのテストを想定します。実際にサーバーを起動し、正しいレスポンスが返却されるかをチェックします。message)}利用するウェブフレームワークがフォアグラウンドでサーバーを起動する場合、テストケース内でサーバーを起動すると、そこでテストがストップしてしまいます。別のターミナルセッションでサーバーを起動した後でテストを実行することもできますがテスト実行以外のプロセスに依存するのは避けた方がよいでしょう。goルーチン内でサーバーを起動することで、テストケース内で完結するようにしてみます。0.021sログからも実際にサーバーが起動しているのがわかります。上述の例では正しく動いているように見えました。サーバーの起動に時間がかかってしまう場合はどうでしょうか。}ウェブフレームワークechoのコードに手を加え、サーバーが起動する際にSleep処理を追加しました。refusedのエラーが出てしまいました。この場合、サーバーが立ち上がるまで待つといった工夫をしなければなりません。サーバーの起動待ちを実装するのは面倒ですが、簡単に実現できる方法が用意されています。ここではgoルーチンを使わない方法でテストを書き直してみましょう。httptestを利用してテストを実行するGolangでは、Webサーバーのテストをサポートするnet/http/httptestも用意されています。このパッケージを利用することで、routingのテストも容易になります。シンプルに記述することができます。0.013shttptest.NewServerすることでラップされたサーバーが立ち上がります。ウェブフレームワークのStart()をコールしているわけではないので、Sleepされません。ポートも自分で指定せずにランダムで空いているポートを利用してくれます。リクエストをシミュレーションするhttptestではサーバーを起動するほか、リクエストをシミュレーションする方法を用意しています。レスポンスはResponseRecorderを介して行われます。Recorderを利用することでレスポンス内容の取得も楽になります。レコーダーのBodyはio.Readerにバッファ機能をつけたリッチなbytes.Budder型となっています。そのためString()で変換することができ、テストもシンプルに記述できました。0.011s最後にこれまで3回に渡ってGolangが標準で提供しているテストの機能の一部を紹介しました。言語としてテストを強くサポートしていることが感じられたのではないでしょうか。紹介しきれていない機能やオプションなどがたくさんあります。今後も有益な機能について紹介できればと思っております。UIテストハンズオンを実施しましたこんにちは。SWETグループの外山(@sumio_tym)です。先日、社...2019-04-26テストの社内普及のための取り組みとして、Androidテストハンズオンを実施しましたこんにちは、SWETグループの田熊です。先日、社内のAndroidア...2018-10-10WebdriverIOでAppiumを使う勘所こんにちは。SWETの外山(@sumio_tym)です。SWETの一員になっ...2018-05-10SWETの新メンバーから見て驚いたこと、そこから生まれたDIライブラリ不使用宣言はじめまして!4/1よりSWETに加わった@Kuniwakです。(1)リンクプライバシーポリシースターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。