Testing

Integration Tests

Exercise the complete application without opening a network port.

By Guillermo Alvarez - Published Updated

Test complete workflows

Integration tests belong in the application test package:

test/application_test.go

Use the real handler:

handler := appinit.App()

Then exercise a workflow:

list := httptest.NewRecorder()
handler.ServeHTTP(list, httptest.NewRequest(http.MethodGet, "/posts", nil))
if list.Code != http.StatusOK {
    t.Fatalf("list status = %d", list.Code)
}

show := httptest.NewRecorder()
handler.ServeHTTP(show, httptest.NewRequest(http.MethodGet, "/posts/hello-golazy", nil))
if show.Code != http.StatusOK {
    t.Fatalf("show status = %d", show.Code)
}

Cover public assets

Complete application tests should include embedded public files:

asset := httptest.NewRecorder()
handler.ServeHTTP(asset, httptest.NewRequest(http.MethodGet, "/assets/importmap.json", nil))

if asset.Code != http.StatusOK {
    t.Fatalf("asset status = %d", asset.Code)
}

Run concurrency checks

Controllers are request-local. Exercise concurrent requests under the race detector:

var wait sync.WaitGroup
for range 20 {
    wait.Add(1)
    go func() {
        defer wait.Done()
        response := httptest.NewRecorder()
        handler.ServeHTTP(response, httptest.NewRequest(http.MethodGet, "/posts", nil))
        if response.Code != http.StatusOK {
            t.Errorf("status = %d", response.Code)
        }
    }()
}
wait.Wait()