写单元测试的12个好处

发表于:2016-9-29 11:01

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:江边望海的博客    来源:51Testing软件测试网采编

  「写单元测试的好处是什么?」
  这个问题非常难以回答。通常只能得出「只有写了才知道」这种含糊不清的答案。
  我最近找到Tim King在2006年的 文章 ,非常完整的回答了这个问题。
  看过之后觉得获益良多,翻译出來和大家分享。
  为什么工程师会讨厌写单元测试?为什么他们会拒绝先写单元测试?不用解释了,那些接口我全听过。我知道真正的原因为何。
  大部份的工程师根本没认真试过测试先行。不然就是当下的环境不支持他们写,导致他们不知道自己在干嘛。前者的情況居多。最后他们就找接口:「我们没时间写单元测试」、「单元测试不能完全保证程序代码品质」。这是在替自己的窘境找理由,而不是真的觉得不写比较好。有趣的是,当这种人直接在你面前开发,你常会看到他开发得很不顺,进度常常在开倒车。目睹这种事满有趣的。但他依旧不会收回原本的看法、依旧不愿意先写测试。这种坚持根本有害。
  Kent Beck在《Test Driven Development By Example》书中提到,测试先行有3个步骤:
  1. Red :写个能表达你打算如何使用那段code的测试,还有你期待它做什么。这个测试会失败。很多界面会用红色信息来表示它。
  2. Green :写出足够的code來让那个测试成功,但別多写。如果你想写更多code,像是检查某些错误的話,那就先另写一個测试表达它。当下只要写刚好够的code去通过测试即可。
  3. Refactor :把多余的code清理一下,然后改善整体设计。之后再跑一次测试,確保沒弄坏什么地方。
  重复这些步骤直到功能做完。这个流程超级简单。为什么工程师会畏惧它?因为这会逼他们从根本上改变开发习惯。
  我们认为自己在写code前不需要先去思考,这些code到底要做什么。
  你如何解決一个软件问题?学校是怎么教的呢?第一步怎么走?你大概只想着如何解決问题本身。你心想:「我要写哪些code来实现出解決方案?」其实你不应该先想「我要写哪些code」,你要先想「我要怎样才能确定问题已经被解決了?」
  我們直觉认为一段code的正确与否,只要执行一次就知道了,超明显的,何必写那种根本废话的测试?就是这种根深蒂固的想法,导致大部份的人改不了开发习惯。
  成功跨过那道鸿沟的人,可以感受到下列几项好处。我全部体会过。不用完全信我,你自己试试看就知道了。
  1. 单元测试保证你的code真的能动
  这会让bug减少。当然,单元测试不能取代系统测试和验收测试。但单元测试能补足他们的短处。
  2. 你会得到一组低层的regression-test suite
  这让你随时可以回头去检查有否哪些坏掉、bug在哪。很多团队会每天把整组测试跑一遍。這让你在把程序交给品管部门之前,可以很轻松的把bug抓出來。
  3. 让你改善系统设计的時候,不怕弄坏系统
  其实就是测试先行3步骤的第3步。通常测试先行写出來的code不太需要重构。我看过很多超糟糕的系统,就像精神病患一样,根本无法搞定。如果有准备好单元测试,你就可以对系统里面最难搞的部份做出有效的重构。
  4. 写测试会让coding更好玩
  你会先搞懂自己的code要做什么。然后再让它完成任务。就算系统还沒全做完,你还是能看到code真的动起來,而且真的沒出错。你会得到一种「我完成了!」的感觉。每分钟都会不断感受到喔。只要试试测试先行,你就会整个人high起來、对自己的作品感到骄傲、被激励去完成更多事情。
  5. 它們可靠地展現目前進度
  你不用為了等整個系統組裝起來而多等一個月。在系統完成之前你就能展示進度了。不但能說自己寫了code,還能真的跑給別人看。傳統開發有件事搞錯了。「完成」不等於你寫了code然後丟出去。「完成」應該是你的code能在系統裡跑,而且沒bug。寫測試會讓你更接近這點。
  6. 單元測試是一種使用範例
  我們都碰過那種不知道怎麼用的library。通常我們會先去找範例程式碼。使用範例可算是一種文件。但公司內部的code通常不會有範例可看。所以只好慢慢試、在系統內東找西找了。因為那個同事可能根本離職了,想問他都沒辦法。單元測試可以當作一種文件。當你不知道Foo類別怎麼用,去看一下單元測試怎麼寫的即可。
  7. 測試先行會強迫你寫code前先做規劃
  先寫測試會逼你在動手開發前把必須完成的事和整體設計想過一遍。不但讓你更專注,還能讓設計更漂亮。
  8. 先寫測試能減少bug的成本
  越早發現bug越容易修。之後出現的bug通常是改了好幾個地方才出現的,
  導致很難抓出哪裡導致了bug。一開始先找出bug在哪,然後要重新回想這段code是怎麼寫的,因為可能是幾個月前寫的。最後才終於弄懂,搞出一套解法。只要能減少抓bug以及修好bug的時間,幾乎都算大賺。如果在成品交給品管部門或是顧客之前,我們只花幾天就找出bug,通常算是很幸運。那幾花幾分鐘就找出bug呢?測試先行就能做到這點。
  9. 它比代碼檢查的效果好
  有人說事前代碼檢查比事後測試系統更好,因為成本比較低。在系統完成之後才測試系統,要修好bug可說是麻煩多了。越早發現bug,就越簡單、越便宜、越好搞定。代碼檢查的好處就在這:只花幾天就能抓出bug,不需要等幾個月。但是測試先行成本更低。只要幾分鐘就抓出bug,連幾天都不用。
  10. 幾乎解決了「開發者瓶頸」(coder’s block)
  不知道下一行寫什麼嗎?就跟「作家瓶頸」(writer’s block)一樣,開發者瓶頸很可能是個大問題。測試先行有系統地處理開發上關於結構的部份,讓你能專心在需要創造的部份。你可能會卡在下段code不知道怎麼測、該怎麼通過測試,但你永遠不會因為下一步卡住。通常會有完全相反的結果:你很想在累倒之前休息一下,但因為清楚看到前面的錄了,所以根本不想停下來。
  11. 單元測試讓設計更棒
  測試一小塊code會強迫你定義清楚那段code負責什麼。如果測起來很簡單,就表示它的責任很明確,cohesion很高。如果一段code能被單元測試,那就表示它很容易就能放進系統之中,就跟它很容易放進測試之中一樣。它跟相關的code只具有loose coupling 。 High cohesion與loose coupling代表了出色、好維護的設計。容易測試的code也很容易維護。
  12. 寫測試會讓開發速度更快
  不寫單元測試也許會讓速度更快,但無法保證code真的能跑。開發上會花一堆時間在在事後的修bug。測試先行會消除這類的浪費,從一開始就做對、讓bug更好修。
  就算好處這麼多,很多工程師還是繼續維持他們的老樣子。如果你在組織裡極度重視流程,你跟他們一部份人會起衝突。我只能祝你好運。記住一件事,人們不會因為一個東西聽起來不錯就買帳。他們只有在極度渴望、超想得到手來品嚐時才會買帳。希望以上幾點可以幫助你說服他們。
  不過,如果你是前者,也就是那種頑固的工程師,不在乎好的軟體設計,只在乎堅持己見…。嗯,我覺得你還真可憐。
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号