Skip to main content

Time for Some Better Wttr Tests

·284 words·2 mins·
Table of Contents
Building a Wttr client in Go - This article is part of a series.
Part 4: This Article

We need to improve our tests. A few things we can quickly improve:

  • Make tests run in parallel
  • Test failure edge cases better
  • Make sure our acceptance tests aren’t dependent on external services

Deliver a baby in 1 month instead of nine
#

Go makes running your tests in parallel easy with the parallel function. Just make sure to use common sense and take side effects into account. For example, if you use environment variables in your tests, parallel tests will produce funky results. We’ll get back to environment variables in tests later on.

func TestFoo(t *testing.T) {
    t.Parallel()
    // ...
}

Test your failures
#

Currently, we only test the happy path. We should test the edge cases as well. To keep things orderly, let’s run subtests for each edge case we want to test.

func TestAPIClient_CurrentWeather(t *testing.T) {
// Run the test in parallel
t.Parallel()

t.Run("can get the current weather", func (t *testing.T) {
    // Run the subtest in parallel
    t.Parallel()

    // Create a test server
    srv := httptest.NewServer(http.HandlerFunc(func (
    w http.ResponseWriter,
    _ *http.Request,
    ) {
        // Return a 200 response with a fixed string
        _, _ = w.Write([]byte("Weather report: honolulu"))
        w.WriteHeader(http.StatusOK)
    }))
    defer srv.Close()

    client := wttrclient.NewWTTRClient(srv.URL)
    got, err := client.CurrentWeather(t.Context())

    require.NoError(t, err)

    want := "Weather report: honolulu"

    assert.Contains(t, got, want)
})

t.Run("can handle bad connections", func (t *testing.T) {
t.Parallel()

client := wttrclient.NewWTTRClient("")
_, err := client.CurrentWeather(t.Context())

require.Error(t, err)
assert.ErrorContains(t, err, "unsupported protocol scheme")
})

t.Run("can handle non 200 responses", func (t *testing.T) {
t.Parallel()

srv := httptest.NewServer(http.HandlerFunc(func (
w http.ResponseWriter,
_ *http.Request,
) {
w.WriteHeader(http.StatusInternalServerError)
}))
defer srv.Close()

client := wttrclient.NewWTTRClient(srv.URL)
_, err := client.CurrentWeather(t.Context())

require.Error(t, err)
assert.ErrorContains(t, err, "invalid response status: 500")
})
}

Fail fail fail
#

Building a Wttr client in Go - This article is part of a series.
Part 4: This Article