Share E-Book
Scan to open this page

Scan with your phone to open this page

Author: Bitfield Consulting

No description

AI Reading Assistant

Whole-book reading guide from stratified index samples; jump to passages in the text

AI guide
# The Power of Go Tools ## 【One-Line Pitch】 A practical, test-driven guide to building robust, reusable Go programs by mastering the language's tooling philosophy—perfect for intermediate Go developers who want to write production-quality code that's easy to test, maintain, and share. ## 【Book Arc】 - **Opening (~0%–10%)**: Establishes the core principle that `main` should be a thin wrapper—all substantive logic belongs in importable, testable packages. Builds a simple "hello" program to demonstrate how to structure code for testability. - **Early (~10%–23%)**: Introduces functional options pattern for configuration, then builds a line/word counting CLI tool using test-driven development. Shows how to test command-line programs as actual executables using script tests, and demonstrates the payoff of reusable package design when adding new commands. - **Early-Middle (~23%–39%)**: Covers file I/O testing with go-cmp for byte comparison, idempotent test design, and permission handling. Emphasizes the philosophy that well-designed applications need minimal logging—prefer stdout/stderr and metrics over verbose logs. - **Middle (~39%–48%)**: Explores filesystem abstraction with `io/fs`, `fs.WalkDir`, and `MapFS` for fast, dependency-free testing. Includes benchmarking to compare real filesystem operations against in-memory alternatives. - **Late (~48%–end)**: Demonstrates wrapping external commands (like macOS `pmset`) in Go packages, using regular expressions to parse command output, and testing integration with external dependencies through build tags and isolation techniques. ## 【Key Takeaways】 - **Keep `main` trivial** (Early): The `main` function should only call an entrypoint from your package—nothing more. This makes all substantive code testable and reusable by other programs, avoiding "dead end" code that can't be imported. - **Functional options enable safe configuration** (Early): Use the `option func(*counter) error` pattern to validate settings at construction time. This guarantees fields are always valid without repeated checks, and prevents nil inputs from causing panics later. - **Test CLIs as CLIs** (Early): Use script-based tests with `exec` and `stdout` assertions to verify your command-line tool behaves correctly as a real executable—no need to build binaries or write complex test plumbing. - **Delegate commands to `Main...` functions** (Early): When adding new commands (like `MainWords` alongside `MainLines`), keep each delegate short and focused. This avoids flag-based switching and makes each command easy to understand and maintain independently. - **Ask "what question does this log answer?"** (Early-Middle): Before adding logging, verify it serves a purpose. Most well-designed applications need minimal logging—send errors to stderr and use metrics (like Prometheus format) for aggregate information instead. - **Use `MapFS` for fast filesystem tests** (Middle): Testing functions that take a filesystem is dramatically faster with in-memory `MapFS` than with real disk trees. Implied folders from pathnames work automatically, eliminating I/O overhead. - **Prefer `fs.WalkDir` over recursive file walking** (Middle): The standard library's filesystem abstraction handles arbitrary-depth trees efficiently without stack memory concerns, and the error parameter gives you control over permission issues. - **Wrap external commands when replication is impractical** (Late): When a system command (like `pmset` for battery status) requires complex system calls, wrapping it in a Go package with regex-based output parsing is simpler and equally portable. ## 【Reading Tips】 - **Deep-read the early chapters (0%–23%)**: The foundational patterns—thin `main`, functional options, script testing—are used throughout the rest of the book. Master these before moving on. - **Skim the code listings, focus on the reasoning**: The book's value is in *why* designs are chosen (e.g., why `Main` returns an int exit status). Pay attention to the problem-solution narrative rather than typing out every example. - **Watch for the "shameless duplication" moments**: The author deliberately shows imperfect solutions (like copying `MainLines` to create `MainWords`) to demonstrate refactoring opportunities. Note how the package design makes this duplication harmless. - **Try the benchmarking section hands-on**: The `MapFS` vs. real filesystem benchmark is worth running yourself to internalize the performance difference and understand benchmark output format. - **Skip ahead if you're not on macOS**: The `pmset` example is macOS-specific, but the principles (wrapping external commands, parsing output with regex) apply universally—substitute `acpi` or `powercfg` as needed. ## 【Coverage Limits】 Excerpts cover roughly the first half of the book (through ~48%), including testing philosophy, CLI construction, filesystem abstraction, and benchmarking. Later chapters on shells, HTTP client packages, and advanced integration testing are only partially represented in the source material. ##
Excerpt 1
om the example repo, if you like): package main import ( "github.com/bitfield/hello" ) func main() { hello.Print() } (Listing hello/2) This won’t work yet, o...
View in text
Excerpt 2
like: “If a filename is specified on the command line, the counter should count the lines in the specified file. Otherwise, it should count lines from standa...
View in text
Excerpt 3
utput file, and that it contains exactly the bytes we want. To do that, we can use os.ReadFile to open and read the file’s contents as got. Now, how should w...
View in text
Excerpt 4
tty fast! Can we do better using the MapFS-based filesystem? Let’s find out: func BenchmarkFilesInMemory(b *testing.B) { fsys := fstest.MapFS{ "file.go": {},...
View in text
Excerpt 5
on, though; why not? The answer is that real users wouldn’t normally want to enable dry-run mode, so they’d always have to supply a “mystery false”: shell.Ne...
View in text
Excerpt 6
r reading, in the same sort of way that we discussed in the chapter on arguments. You can use script to construct the sort of simple one-off pipelines that w...
View in text
Excerpt 7
Listing weather/4) Refactoring FormatURL is straightforward. We’re not adding any new behaviour, just moving paperwork around: func (c Client) FormatURL(loca...
View in text
Excerpt 8
"You can see here", "a battery, a key,", - " and", } (Listing game/4) How can we refactor our existing test to use the new testCase struct type? Well, let’s...
View in text
Tags
AI categories
Programming LanguageGotesting
Publisher: Bitfield Consulting
Publish Year: 2023
Language: English
File Format: PDF
File Size: 3.6 MB
Text Preview (First 20 pages)
Registered users can read the full content for free

Register as a Gaohf Library member to read the complete e-book online for free and enjoy a better reading experience.

Generating text preview…