Go中的TDD:无忧无虑地编写代码

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

引言:为什么TDD不是信仰,而是救生圈

\n\n

想象一下,你在老房子里修理电线。你关掉了电闸,但仍然不敢把手伸进配电箱。没有测试就修改项目的开发者,大概就是这种感觉。尤其是在Go中——静态类型会给人一种虚假的安全感。

\n\n

Go中的测试驱动开发(TDD)不是一种时尚潮流,也不是一种教派仪式。这是一种将重构的恐惧转化为自信的方法论。根据IBM的研究,采用TDD的项目缺陷减少了40%。而在Go中,编译器已经过滤掉了一半的错误,TDD则解决了剩下的一半。

\n\n

在本文中,我们不会进行说教。我们将解决一个实际任务:编写一个简单的URL缩短HTTP服务。并走完TDD的完整路径——从红色测试到绿色测试再到重构。开始吧!

\n\n

什么是真正的TDD?

\n\n

如果你听说过红-绿-重构——你已经入门了。如果没有——记住三个简单的步骤:

\n\n
    \n
  1. 红色——编写一个注定失败的测试(因为功能还不存在)。
  2. \n
  3. 绿色——编写最少的代码使测试通过。不追求完美,只要能用。
  4. \n
  5. 重构——在不改变行为的前提下改进代码。测试是我们的保障。
  6. \n
\n\n

在Go中,由于内置的testing包,这个循环尤其令人愉悦。你不需要安装jest或pytest——标准库中已经包含了一切。但许多初学者忽略了测试,认为Go已经很“安全”了。这是错误的。

\n\n

为什么TDD在Go中比其他语言效果更好?

\n\n

Go社区崇尚简单。在这里,TDD不会变成充满模拟和桩代码的官僚主义。相反,你编写的是表格驱动测试——紧凑、可读、易懂。一个测试用例就是一行。而且,Go测试运行速度很快。几百个用例只需几毫秒是常态。

\n\n

顺便提一下,Go官方博客多次强调:“测试就是文档”。如果你的测试读起来像规范——那么你做对了。

\n\n

配置环境:开始前需要什么

\n\n

假设你已经安装了Go。如果没有——运行brew install go或apt install golang-go。检查版本:go version。本文需要Go 1.21+。

\n\n

创建项目:

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

完成。不需要任何框架——只需要标准库和Go测试驱动开发。

\n\n

编写第一个测试:红色

\n\n

假设我们想要一个函数Shorten(url string) string,它将长URL转换为短哈希。目前它还不存在——这很好。编写测试:

\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返回了空字符串")\n    }\n\n    if len(result) > 10 {\n        t.Errorf("期望短哈希,得到%d个字符", len(result))\n    }\n}
\n\n

运行:go test -v。看到红色(技术上来说是编译错误)。Shorten函数不存在。很好,我们处于红色阶段。

\n\n

最少代码:绿色

\n\n

现在编写刚好能让测试通过的代码。不需要任何加密,只是一个哈希:

\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]) // 取前4个字节\n}
\n\n

再次运行测试。绿色?太好了。但代码很糟糕——哈希有冲突,我们甚至没有检查

博客

书籍推荐