liveBook · Manning

Test

As explained in Go by Example

A test case is a defined test scenario consisting of inputs, execution conditions, and expected behavior or results.

Testing checks that code behaves as expected now and after later changes. It also exposes whether code is easy to use, isolate, and adapt, so testability matters alongside finding bugs. Even broad coverage cannot prove a program is bug-free. section 1.1.3 section 2.0

In Go, tests live in *_test.go files as functions named TestX that receive *testing.T. Run them with go test. Use t.Fatalf when a failure makes the rest of that test invalid; use t.Errorf when later checks can still reveal useful failures. A fatal failure stops only its own test function, not other tests. section 2.3 section 2.3.1

Test a URL parser

Call Parse with a URL, stop if parsing returns an error, then compare the returned URL with the expected Scheme, Host, and Path. Test String separately by constructing a URL and checking that it reassembles the original URL string. Failure messages should report both got and want values. section 2.3.1

A test case is a named scenario containing input and expected output. Table-driven tests keep cases in a slice of structs and run shared logic for each row. This reduces duplicated test code, makes new cases cheap to add, and lets a bug become a permanent regression case. section 2.4 section 2.4.1

Listing 2.7 A table-driven test case (url/url_test.go)
var parseTests = []struct { #1
    name string  #1
    uri  string  #1
    want *URL  #1
}{
    {  #2
        name: "full",   #2
        uri:  "https://github.com/inancgumus",   #2
        want: &URL{   #2
            Scheme: "https",   #2
            Host:   "github.com",   #2
            Path:   "inancgumus",   #2
        },   #2
    },   #2
    {  #3
        name: "without_path",   #3
        uri:  "https://github.com",   #3
        want: &URL{   #3
            Scheme: "https",   #3
            Host:   "github.com",   #3
            Path:   "",   #3
        },   #3
    },   #3
    /* many more test cases can be easily added */ #3
} #3

Inspect a compact test-case table: each row pairs a descriptive name and URL input with the expected parsed URL. section 2.4.1

A plain table loop has a trade-off: Fatalf in one case skips all remaining cases, and individual rows cannot be selected with the run flag. Subtests give each case its own *testing.T, so a fatal failure stays local and cases can be addressed independently. section 2.4.4 section 2.5.3

Choose the test level to fit the risk. CLI tests verify user-visible behavior, while unit tests isolate components such as a flag parser for edge cases. Dependencies can be substituted to make units testable; handler tests can invoke an HTTP handler with a request and ResponseRecorder, then inspect status and body. section 5.0 section 5.5 section 8.7.2

How Go by Example covers it

How deep it goes
Builds runnable Go tests through conventions, assertions, table cases, subtest failure isolation, and unit or handler testing.
Examples
Demonstrates URL parsing and formatting, CLI flag parsing, and an HTTP health handler with ResponseRecorder.
What it assumes
Assumes basic Go, including variables, pointers, methods, interfaces, slices, and anonymous structs.
What you can do after
Apply it via Go’s testing package and go test to write, run, organize, and diagnose automated tests.
How it connects
Connects testing with testability, dependency injection, unit testing, subtests, build tags, and HTTP handlers.

Also explained in

Compare how 53 books explain test →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Go by Example. The section links point to the parts of the book it draws on.