五反田もくもく会 #でぶつー に参加してきた

近所で五反田もくもく会という会が行なわれるということで参加してきた。

参加者は15人ほど。

ビールやらおかしやらカップ麺やらをつまみながら好き勝手に開発する。

19:00~22:00で後半の30分は成果を発表という流れ。

ほどよく緊張感もありそれなりに集中できたと思う。

LTメインのイベントも好きだけど、こういう会社以外のエンジニアの方々と実際に手を動かしながら話合える会のほうが個人的には好き。

やったこと

はじめはswiftを触ってみようと思ってたんだけど、xcodeのアップデートが冗談じゃないくらい時間がかかる様子で諦めたざるをえなかった。残念。

で、実際にやったことはSOTAさんのMartini(+Ginkgo)をWerckerでCIしてHerokuにデプロイするという記事を見ながらGoのウェブアプリについて遊ぶことにした。

とりあえずwerckerからherokuに自動デプロイするとこまでできたので良い。

実際のコードは以下。

以下にはざっとそのログを書いておく。

martini

sinatraライクにwebアプリをつくれる。

$ go get github.com/go-martini/martini

準備。

$ mkdir sample-go-app
$ cd sample-go-app

Procfileとメインファイル作成

$ echo "web: $(basename `pwd`)" > Procfile
$ subl server.go
// server.go
package main

import "github.com/go-martini/martini"

func main() {
    m := martini.Classic()
    m.Get("/", top)
    m.Run()
}

func top(params martini.Params) (int, string) {
    return 200, "Hello!"
}

git管理してherokuにpush。heorkuには登録済み+herokutoolbelt導入済み。

(godepはgitですでに管理しているアプリにしかgodep saveできない)

$ git init
$ go commit -am "first commit"
$ go get github.com/kr/godep
$ godep save
$ go commit -am "add godep"
$ heroku create -b https://github.com/kr/heroku-buildpack-go.git
$ git push heroku master

アプリにアクセスすればHello Worldが表示される

$ heroku open

Ginkgo

GinkgoはGoでBDDできるフレームワーク

使い方はここが詳しい。→http://onsi.github.io/ginkgo/

ざっと手順。

インストール

$ go get github.com/onsi/ginkgo/ginkgo
$ go get github.com/onsi/gomega

初期化。suiteファイルが作成される。

$ ginkgo bootstrap

テスト書く。流れとしては、

  • go genarate テスト対象のファイル名(例えばbook.goのテストならgo genarate book)
  • 作成されたテストファイルにdescribe,context,it,expectなどを用いてテストを書いていく
  • $ ginkgoを実行するとsuite_testのTestSampleAppGo()が実行されて、全specが実行される

といった感じ。

sample_app_go_test.go

package main

import (
    . "github.com/onsi/ginkgo"
    . "github.com/onsi/gomega"
)

var _ = Describe("Sample", func() {
    Context("top()", func() { // top()はserver.go内の関数
        It("return 200 Status", func() {
            RequestToRoot("GET", top)
            Expect(recorder.Code).To(Equal(200))
            Expect(recorder.Body).To(ContainSubstring("Hello"))
         })
     })
})

sample_app_go_suite_test.go

package main // ここがデフォルトだとsample_app_goとかになってるけど今回はmainで。

import (
    "fmt"
    "github.com/go-martini/martini"
    . "github.com/onsi/ginkgo"
    . "github.com/onsi/gomega"
    "net/http"
    "net/http/httptest"
    "testing"
)

var (
    recorder *httptest.ResponseRecorder
)

func RequestToRoot(method string, handler martini.Handler) {
    m := martini.Classic()
    m.Get("/", handler)
    recorder = httptest.NewRecorder()
    req, _ := http.NewRequest(method, "/", nil)
    m.ServeHTTP(recorder, req)
    fmt.Println(recorder)
}

func TestSampleAppGo(t *testing.T) {
    RegisterFailHandler(Fail)
    RunSpecs(t, "SampleAppGo Suite")
}

ここまで書いてテストが通ったらgithub or bitbucketにpushしとく。

wercker

werckerは無料のCIサービス。TravisCIみたいな感じ。

とりあえずここ見ながらアカウント登録しとく。 http://blog.mah-lab.com/2014/01/08/rails-wercker-heroku-deploy/

bitbucketを使うならこれで。 http://razokulover.hateblo.jp/entry/2014/05/21/000306

そしたらwerckerさんがこういうファイルを作ってくれるのでそれをリポジトリに追加し、pushすれば自動でテストが走る。

herokuにデプロイしたい場合はherokuのMyAccountからheroku APIを取得し、werckerのappのdeploy設定のところに登録。

box: wercker/golang
# Build definition
build:
  # The steps that will be executed on build
  steps:
    # Sets the go workspace and places you package
    # at the right place in the workspace tree
    - setup-go-workspace

    # Gets the dependencies
    - script:
        name: go get
        code: |
          cd $WERCKER_SOURCE_DIR
          go version
          go get -t ./...

    # Build the project
    - script:
        name: go build
        code: |
          go build ./...

    # Test the project
    - script:
        name: go test
        code: |
          go test ./...
deploy:
  steps:
    - heroku-deploy

ここまでくれば、アプリをgithub or bitbucketにpushするたびにCIしてherokuへの自動デプロイが可能になる。




会場提供/運営をしていただいたモバイルファクトリーの皆様ありがとうございましたー。


[追記]

ついにyapcramenがやってきて困ってる。