Test-driven development makes tests the design specification: begin with measurable behavioral targets, then implement code until those tests pass. This turns testing from defensive verification into a tool for shaping APIs and enforcing contracts. section 8.0 section 8.8
A practical Go workflow proceeds in small, testable steps:
- Define the API and its required behavior before implementing the underlying type. section 8.5
- Create a compilable code skeleton, initialize the module, and write tests against the intended behavior. section 8.5
- Run go test with deliberate failures, then implement behavior incrementally and use passing tests as feedback. section 8.5.2 section 8.5.6
Calculator with memory
Design a Calculator with Calculate, Store, and Recall methods. Specify addition, subtraction, multiplication, division, remembered results, unknown-operation errors, and division-by-zero errors. Start with an unimplemented skeleton; tests should assert both the expected error and a zero result for invalid calculations. Implement fields for memory, the latest result, and the latest error, then finish the methods until go test passes. section 8.5 section 8.5.2 section 8.5.6
Listing 8.10 Calculator skeleton
package basicmath
import "errors"
var (
ErrDivByZero = errors.New("divide by zero")
ErrUnknownOperation = errors.New("unknown operation")
)
type Calculator struct{}
func NewCalculator() *Calculator {
return &Calculator{}
}
func (c *Calculator) Calculate(operation string, a, b int) (int, error) {
// not implemented
return 0, errors.New("unimplemented")
}
func (c *Calculator) Store() {
// not implemented
}
func (c *Calculator) Recall() int {
// not implemented
return 0
}
Inspect the compilable Calculator skeleton that provides the API surface before behavior is implemented. section 8.5
Listing 8.12 Testing divide by zero
func TestErrDivideByZero(t *testing.T) {
c := basicmath.NewCalculator()
got, err := c.Calculate("div", 1, 0)
if !errors.Is(err, basicmath.ErrDivByZero) {
t.Errorf("expected ErrDivByZero - got: %v", err)
}
if got != 0 {
t.Errorf("error result should be 0 - got: %d", got)
}
}
Inspect a focused test that checks both the sentinel error and returned value for division by zero. section 8.5.2














