LoginSignup
16
16

More than 5 years have passed since last update.

Web Application周りのテスト方法

Posted at

色々な方法があると思うけど、簡単な3種類をまとめておく。

テスト対象のコード

package main

import (
    "net/http"

    "github.com/facebookgo/grace/gracehttp"
    "github.com/sebest/xff"
    "goji.io"
    "goji.io/pat"
    "golang.org/x/net/context"
)

func main() {

    mux := goji.NewMux()

    mux.HandleC(pat.New("/*"), NewMux())

    err := gracehttp.Serve(&http.Server{Addr: ":8080", Handler: mux})
    if err != nil {
        panic(err)
    }
}

func NewMux() *goji.Mux {

    mux := goji.NewMux()

    mux.Use(xff.Handler)
    mux.HandleFuncC(pat.Get("/:name"), Hello)

    return mux
}

func Hello(ctx context.Context, w http.ResponseWriter, r *http.Request) {

    w.Write([]byte("Hello, " + pat.Param(ctx, "name") + "\nRemote Address: " + r.RemoteAddr))
}

テストコード

その1: 関数に対してテスト

普通に関数に対してテストを行う。
特に難しいことは、していない。

func TestHello(t *testing.T) {

    t.Parallel()

    ctx := context.WithValue(context.Background(), pattern.Variable("name"), "john")

    req, err := http.NewRequest("", "", nil)
    require.NoError(t, err)

    resp := httptest.NewRecorder()
    Hello(ctx, resp, req)

    require.Equal(t, http.StatusOK, resp.Code)
    require.Contains(t, resp.Body.String(), "Hello, john")
    require.NotContains(t, resp.Body.String(), "127.0.0.1")
}

その2: Multiplexer に対してテスト

Routing とか、 Middleware とかテストしたい時は、こっちの方が適切だと思う。

func TestUsersMultiplexer(t *testing.T) {

    t.Parallel()

    mux := NewMux()

    req, err := http.NewRequest("GET", "/john", nil)
    require.NoError(t, err)

    resp := httptest.NewRecorder()
    mux.ServeHTTP(resp, req)

    require.Equal(t, http.StatusOK, resp.Code)
    require.Contains(t, resp.Body.String(), "Hello, john")
    require.NotContains(t, resp.Body.String(), "127.0.0.1")
}

その3: Server を立ち上げてのテスト

E2E 的なテストをしたい時や、 RemoteAddr を用いている場合は、こちらの方法が良い。

func TestServer(t *testing.T) {

    t.Parallel()

    ts := httptest.NewServer(NewMux())
    defer ts.Close()

    resp, err := http.Get(ts.URL + "/john")
    require.NoError(t, err)

    defer resp.Body.Close()

    body, err := ioutil.ReadAll(resp.Body)
    require.NoError(t, err)

    bodyStr := string(body)

    require.Equal(t, http.StatusOK, resp.StatusCode)
    require.Contains(t, bodyStr, "Hello, john")
    require.Contains(t, bodyStr, "127.0.0.1")
}

他にも良い方法あったら、コメント下さい。

16
16
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
16
16