使用 TDD 做開源貢獻(xiàn)
TDD
TDD,即測試驅(qū)動(dòng)開發(fā),要求先寫測試,再寫實(shí)現(xiàn)。除了日常開發(fā)外,其實(shí)在做開源貢獻(xiàn)時(shí),也非常適合。TDD 要細(xì)聊的話,內(nèi)容可以多到寫一本書,甚至還有不同的流派存在。
但是最重要的原則我覺得很簡單,那就是:先寫測試,再寫實(shí)現(xiàn)。
舉個(gè)例子
最近又給一個(gè)開源項(xiàng)目提了一個(gè) PR,再一次使用了 TDD 大法,正好可以做一個(gè)活生生的例子。這次是修一個(gè) BUG,正好可以展示 TDDer 們是怎么修 BUG 的。
https://github.com/xingxingted/koa-to-express/pull/10
別先修,而是先重現(xiàn)
發(fā)現(xiàn)了 BUG,千萬不要直接修復(fù)!注意,直接修復(fù) BUG 其實(shí)是在直接寫實(shí)現(xiàn)代碼,這就不是 TDD 了。發(fā)現(xiàn)了 BUG,先寫個(gè)測試用例來重現(xiàn)它,這樣當(dāng)你修復(fù)并提交代碼之后,cicd 就會(huì)運(yùn)行這個(gè)測試用例,從而保證在后續(xù)的迭代中同樣的 BUG 不會(huì)再次出現(xiàn)。
在上一篇文章(Free Arch:將 Koa 服務(wù)部署到 Vercel)中聊到,由于 Vercel 的函數(shù)計(jì)算,只默認(rèn)支持 Express,我為了將自己的陳年老 Koa 項(xiàng)目在 Vercel 的函數(shù)計(jì)算里復(fù)活,就需要將它偽裝成 Express,從而使用了一個(gè)開源庫:koa-to-express。這個(gè)庫很好用,然而在某個(gè)場景下會(huì)報(bào)錯(cuò)。這個(gè)場景就是當(dāng)引入了 Koa Router 時(shí),如果請(qǐng)求一個(gè)不存在的路由,就會(huì)報(bào) Internal Server Error。所以先寫個(gè)用例來重現(xiàn)這個(gè)問題:
在測試代碼中創(chuàng)建一個(gè) Koa 服務(wù),并使用 koa-router 對(duì)一個(gè)路由(即 /health)做響應(yīng)。在具體的測試用例里,故意去請(qǐng)求一個(gè)不存在的路由:

修復(fù)
可以看見,對(duì)于修復(fù) BUG,其實(shí)主要代碼往往在寫測試用例上。因?yàn)樽罱K的修復(fù),就加了一行代碼而已:

提交 PR,等待作者回應(yīng)
PR 提了幾天 了,這個(gè)庫的作者并沒有回應(yīng)。但是我已經(jīng)先用起自己修改的版本了,技巧是修改 package.json 對(duì)于包的引用方式,詳見上一篇文章。
其他例子:Skulpt

注意:使用 TDD 做開源貢獻(xiàn),并不保證一定能夠得到維護(hù)者們的采納。上面的例子,也還是在等待中,希望有好的結(jié)果。那為什么拿這個(gè) PR 做例子呢?因?yàn)檫@是一個(gè)非常簡單并又有代表性的例子,方便讓人領(lǐng)會(huì) TDD 修 BUG 的做法。除了這個(gè),我再列舉一個(gè)自己使用 TDD 做開源貢獻(xiàn)并被成功采納的例子,這是我特別自豪的一個(gè)貢獻(xiàn):Skulpt,它可以在瀏覽器中運(yùn)行 python。但是我在使用時(shí)發(fā)現(xiàn)它的中文支持有問題,在進(jìn)一步研究后,發(fā)現(xiàn)其實(shí)是所有的 unicode 字符都不能正常顯示,于是做了改進(jìn)的提交:https://github.com/skulpt/skulpt/pull/223,也可以看到,修復(fù)本身雖然改動(dòng)很小,但是測試代碼占了大頭。

福利
Skulpt 的維護(hù)者們,不僅采納了這個(gè)改動(dòng),還把我的名字放在了他們的官網(wǎng) 上,這讓我感覺非常自豪。

