TDD in Go: Writing Code Without Fear or Blame

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Introduction: Why TDD is Not a Religion, But a Lifeline

\n\n

Imagine you're fixing the wiring in an old house. You flip the main switch, but you're still afraid to put your hands in the panel. That's roughly how a developer feels when making changes to a project without tests. Especially in Go — a language where static typing gives a false sense of security.

\n\n

Test-Driven Development (TDD) in Go is not a trendy fad or a cult ritual. It's a methodology that turns the fear of refactoring into confidence. According to an IBM study, projects using TDD show 40% fewer defects. And in Go, where the compiler already eliminates half the errors, TDD finishes off the remaining 50%.

\n\n

In this article, we won't be giving lectures. We'll take a real task: we'll write a small HTTP service for URL shortening. And we'll go through the entire TDD journey — from a red test to green and refactoring. Let's go!

\n\n

What is TDD Really?

\n\n

If you've heard of Red-Green-Refactor — you're already in the know. If not, remember three simple steps:

\n\n
    \n
  1. Red — write a test that is expected to fail (because the functionality doesn't exist yet).
  2. \n
  3. Green — write the minimum code to make the test pass. Not perfect, just working.
  4. \n
  5. Refactor — improve the code without changing its behavior. Tests are our safety net.
  6. \n
\n\n

In Go, this cycle is especially pleasant thanks to the built-in testing package. You don't need to install jest or pytest — everything is already in the standard library. But many beginners ignore tests, thinking Go is "safe" anyway. And that's a mistake.

\n\n

Why Does TDD in Go Work Better Than in Other Languages?

\n\n

The Go community loves simplicity. TDD here doesn't turn into bureaucracy with mocks and stubs. Instead, you write table-driven tests — compact, readable, understandable. One test case — one line. And yes, Go tests are fast. Milliseconds for hundreds of cases is normal.

\n\n

By the way, the official Go blog has emphasized many times: "Tests are documentation." If your test reads like a specification — you're doing everything right.

\n\n

Setting Up the Environment: What You Need to Start

\n\n

I assume you already have Go installed. If not — brew install go or apt install golang-go. Check the version: go version. Go 1.21+ is sufficient for this article.

\n\n

Let's create a project:

\n\n
mkdir url-shortener-tdd\ncd url-shortener-tdd\ngo mod init url-shortener
\n\n

Done. No frameworks — just the standard library and test-driven development in Go.

\n\n

Writing the First Test: Red

\n\n

Let's say we want a function Shorten(url string) string that turns a long URL into a short hash. It doesn't exist yet — and that's perfect. Let's write a test:

\n\n
// shortener_test.go\npackage main\n\nimport "testing"\n\nfunc TestShorten(t *testing.T) {\n    url := "https://pythonlib.ru/very/long/path?with=params&and=stuff"\n    result := Shorten(url)\n\n    if len(result) == 0 {\n        t.Error("Shorten returned an empty string")\n    }\n\n    if len(result) > 10 {\n        t.Errorf("Expected a short hash, got %d characters", len(result))\n    }\n}
\n\n

Run it: go test -v. We see red (well, technically — a compilation error). The Shorten function doesn't exist. Great, we are at the Red stage.

\n\n

Minimum Code: Green

\n\n

Now we write just enough code to make the test pass. No cryptography, just a hash:

\n\n
// shortener.go\npackage main\n\nimport (\n    "crypto/sha256"\n    "fmt"\n)\n\nfunc Shorten(url string) string {\n    hash := sha256.Sum256([]byte(url))\n    return fmt.Sprintf("%x", hash[:4]) // take the first 4 bytes\n}
\n\n

Run the test again. Green? Excellent. But the code is terrible — the hash is collision-prone, and we don't even check if it's

Blogs

Book Recommendations