ごあいさつ
エンジニアのうぃすきー(@Whisky_shusuky)と申します。弊社ではインフラ・バックエンド・フロントエンドとWeb周りを全般的に対応しております。
最近Goをよく使っているため、以前公開したGinで作ったサンプルAPIにGithub Actionsの設定を追加してCIでtestが回るようにしてみましたのでこの場を借りて紹介しようと思います。
またサンプルAPIの中身については以前Qiitaに記載しましたので必要でしたらご確認ください。
テストの紹介
元々Railsを扱う機会が多かったので、Railsでのrequest specと同様にして実際にapiにアクセスしてレスポンス内容を検証するテストを実行することでAPIの動作を保証したいと思いました。 testfixturesを使えばテスト用DBにテストデータを以下のようにしてyaml形式で定義できます。
- id: 1 shop_name: "test shop name" shop_description: "test shop description"
このデータを以下のようにして実際にAPIにアクセスして取得するテストを書きました
t.Run("returns 200 when GET /", func(t *testing.T) { req, _ := http.NewRequest("GET", testServer.URL+"/api/v1/shops", nil) res, _ := client.Do(req) body, err := ioutil.ReadAll(res.Body) if err != nil { t.Error("[Error]", body, err) } assert.Equal(t, http.StatusOK, res.StatusCode) expectedBody := `{"shops":[{"id":1,"shop_name":"test shop name","shop_description":"test shop description"}]}` assert.JSONEq(t, expectedBody, string(body)) })
Github Actions でテストを回す
上記のテストをgithub actionsで回るように設定しました。
name: test on: push: branches: [ master ] pull_request: branches: [ master ] jobs: golangci: services: mysql: image: mysql:5.7 ports: - 3306:3306 env: MYSQL_ALLOW_EMPTY_PASSWORD: yes BIND-ADDRESS: 0.0.0.0 options: --health-cmd "mysqladmin ping -h localhost" --health-interval 20s --health-timeout 10s --health-retries 10 strategy: matrix: go-version: [1.16.x] os: [ubuntu-latest] name: test runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v2 - name: testing run: ENV_GO=citest bash -c 'go test ./... -v'
ここではservicesのmysqlをデータベースとして使用しております。ローカルではdocker-composeで別途立てたコンテナを使用しているため接続方法が異なってきます。
そこでrun: ENV_GO=citest bash -c 'go test ./... -v'
の形式で渡した環境変数ENV_GO
を使って環境に応じて接続方法が変わるようにして対応しました。若干ハードコード気味ですがそれは置いておいて、こんな感じで環境変数に応じて動作を切り替えることが可能です。
if env == "citest" { datasource = "root@tcp(127.0.0.1:3306)/" dsn = "root@tcp(127.0.0.1:3306)/sampletest?parseTime=true" } else { datasource = "root@tcp(db)/" dsn = "root@tcp(db)/sampletest?parseTime=true" }
これでPRをmaster向けに作るとGIthub Actionsが走ります
むすび
Railsを元々書いていてGoを書き始めた方はrequest specを書きたくなると思います。そのような方の参考になりましたら幸いです。実際にAPIを叩くテストを書いたことが無い方も、APIの動作を担保するという意味では有効だと思いますので試してみるのはいかがでしょうか。