これはGo Advent Calendar 2016の18日目の記事です。今回はGoでE2Eテストを行うためのライブラリagoutiについて書きます。
GoでE2Eテストを書く理由
WebアプリケーションのサーバーサイドをGoで書いている場合、GoでE2Eテストを書くメリットとして
- JavaScriptが得意ではないエンジニア(自分)でもE2Eテストがガリガリかける
- E2Eテスト実行時のカバレッジが取れる=サーバーのコードのどこを通ったかがわかる
があると思っている。特に2番めの理由が大事で、「E2Eテストを全部回した結果、サーバーのこの部分のコードは通っている」とわかるのはけっこう大きなメリットなのではないかと。どこがテストされている・いないを把握することで、「ここはE2Eテストだと難しいからユニットテストでカバーしよう」というような戦法が取りやすいと思う。
じゃあ具体的にGoでどうやってE2Eテストを書くのか、ということを次に説明する。
Go製WebDriverクライアントagouti
GoにはagoutiというSelenium WebDriverのクライアントがあるので、今回はこれを使う。agouti自体は単にWebブラウザを操作するライブラリなので、あわせてChromeDriverなどをインストールする必要がある。MacにChromeDriverをインストールするのはHomebrewでbrew install chromedriver
してインストールするのが楽で、それ以外のOSではChromeDriverのサイトからダウンロードしてすればOK。
一例として、下記のようなagoutiを使うGoのコードを書いて動かすと、Chromeが起動して https://ifconfig.co/ のページが表示されて5秒スリープする。
webDriver := agouti.ChromeDriver() // ChromeDriverを使う if err := webDriver.Start(); err != nil { return err } defer webDriver.Stop() page, err := webDriver.NewPage() if err != nil { t.Error(err) } // Navigateで指定したURLにアクセスする if err := page.Navigate("https://ifconfig.co/"); err != nil { t.Error(err) } time.Sleep(5 * time.Second)
agoutiでWebアプリケーションをテストする
もう少し実践的な例として、フォームに入力された値を表示する簡単なWebアプリをテストするケースを考える。ディレクトリ構成は
- cmd: サーバーの実行ファイル用
- app: Webアプリケーションの本体
- e2e: E2Eテスト置き場
という感じになっていて、全てのコードはgo-e2e-test-sampleのリポジトリに上げてある。
この、単にフォームで送信された名前を表示するだけのWebアプリケーションのコードはこんな感じ。
そして、E2Eテストのコードはこんな感じ。TestIndex
で/
にアクセスしている。
ポイントとしては
- testMainでサーバーとChromeDriverを起動
- TestIndex関数内で
webDriver.NewPage
でPageを生成し、Page.Navigateで起動したサーバーのURLにアクセス Page.FindByXPath
でHTMLの要素を検索してformをSubmit
というような流れになっている。なお、今回はXPathを使ってHTMLの要素を検索しているが、CSS Selectorを使うFindなんかもある。詳しくはgodocを見れば詳しく書いてある。
そして、このe2e_test.go
をgo test
コマンドで実行すると、Chromeが立ち上がってテストが実行される。
$ go test -v ./e2e
カバレッジを取ってみる
では次にカバレッジを取って、どの部分がE2Eテストによって実行されているのかを調べてみる。go testの引数に-coverpkg
と-coverprofile
をつけて実行する。
$ go test -v -cover -coverpkg=./app -coverprofile=cover.out ./e2e
これでcover.out
にカバレッジのためのファイルができるので、go tool cover
でHTMLとして表示してみる。
$ go tool cover -html cover.out
ブラウザが立ち上がって下記のような画面が表示されるので、今回のE2Eテストで実行されているコードがひと目でわかる。
まとめ
- agouti便利
- go testでE2Eテストを実行できるようにしておくと
go tool cover
などのGoエコシステムがそのまま使える