Digging Deeper
Testing
Combine focused package tests with full application HTTP integration tests.
Test at the ownership boundary
Keep focused tests beside the package they exercise:
- Framework renderer, dispatch, application, and routing tests live in
golazy. - Service tests live beside application services.
- Adapter tests live beside
libpackages. - Executable helper tests live in
cmd/app.
Complete application behavior belongs in sample_app/test.
Construct the real handler
Integration tests should use the same composition path as main:
func application() http.Handler {
return appinit.App()
}
This catches broken dependency wiring, route registration, template rendering, dispatch, and public-file setup together.
Exercise requests
Use the standard library:
request := httptest.NewRequest(http.MethodGet, "/posts", nil)
response := httptest.NewRecorder()
application().ServeHTTP(response, request)
if response.Code != http.StatusOK {
t.Fatalf("status = %d", response.Code)
}
Useful assertions include:
- Status code.
Content-Type.Allowfor method errors.- Escaped or rendered body content.
404behavior for missing records and files.- Embedded public-file responses.
Verify request-local controllers
Controller state is mutable, so integration tests should exercise concurrent requests:
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()
Run this under the race detector.
Test rendering boundaries
Framework renderer tests should verify:
- Ordinary values are HTML-escaped.
- View output is composed into the layout.
- Missing views and layouts return contextual errors.
- A renderer cannot be initialized without the default layout.
Application tests should verify only the behavior the application owns.
Release verification
For the framework:
go test ./...
go test -race ./...
go vet ./...
For the sample application:
go test ./...
go test -race ./...
go vet ./...
go build -o /tmp/sample-app ./cmd/app
Use a temporary GOCACHE and CC=/usr/bin/gcc when required by the managed
development environment.