天天躁日日躁狠狠躁AV麻豆-天天躁人人躁人人躁狂躁-天天澡夜夜澡人人澡-天天影视香色欲综合网-国产成人女人在线视频观看-国产成人女人视频在线观看

TDD到底美不美?

  最近CoolShell上的一篇《TDD并不是看上去的那么美》引起了敏捷社區(qū)的高度關(guān)注和激勵辯論。今天,InfoQ甚至專門舉行了一個虛擬座談會《TDD有多美?》,幾位國內(nèi)敏捷社區(qū)的名人專門就此問題展開了深入地討論。不論結(jié)果如何,這種探討和反思的精神還是非常值得贊賞的。事件實際上可以簡單地歸納為一個有一定影響力的開發(fā)人員質(zhì)疑TDD,一群敏捷社區(qū)名人對TDD進(jìn)行解釋和辯護(hù)?,F(xiàn)在,就讓我堅定地站在CoolShell一邊,為對TDD的質(zhì)疑和批判添磚加瓦吧!

  我們首先來看看TDD的核心理念是什么。第一是用例即規(guī)范(Specification by Example),即把測試用例作為需求規(guī)范的一種形式。傳統(tǒng)的需求表達(dá)方式包括文檔,Use Case等,而TDD強(qiáng)調(diào)通過測試用例來表達(dá)需求。另外,TDD的測試用例是黑盒的基于外部接口的,所以,它實際上又是對外部接口的設(shè)計。不把測試用例單純地視為測試,而從需求和設(shè)計的角度來看測試用例是TDD與傳統(tǒng)測試的一個重要區(qū)別。TDD的第二個重要理念是Test First,強(qiáng)調(diào)測試對于實現(xiàn)的驅(qū)動作用,先寫測試用例,再實現(xiàn)和重構(gòu)。Test First的實質(zhì)是先理解清楚需求,并做好外部接口設(shè)計,把它轉(zhuǎn)化為測試用例,然后再來實現(xiàn)和重構(gòu)。

  如果說用例即規(guī)范還彌補(bǔ)了文檔和Use Case在表達(dá)需求時的某些不足,具有一定的好處,那么Test First則有很大的問題,尤其在沒有測試用例失敗之前,不要寫任何一行代碼的極端方式則更是極端的錯誤。

  如果測試用例就是需求和設(shè)計,那么為什么不能先寫出測試用例再來實現(xiàn)呢?這不是我們最熟悉的先需求再設(shè)計再編碼嗎?答案是:不能執(zhí)行的測試用例(Test First)和能執(zhí)行的測試用例有著天壤之別,你寫出了測試用例不代表你就看到了運行的實際效果。

  不能執(zhí)行的測試用例和寫在紙上的文檔相比對實現(xiàn)的指導(dǎo)意義不見得能好到哪里去!除非是一些很簡單的情況下,在實際的軟件開發(fā)中,你很難在沒有執(zhí)行測試用例的情況下寫出真正符合最終需求的測試用例來。比如:你做一個頁面,頁面的效果需求和設(shè)計通常會在真正可以運行之后不斷調(diào)整,在實現(xiàn)之前只能有一個大致的輪廓和方向,許多方面的細(xì)節(jié)要么是沒想清楚,要么是完全沒想到,不可能一蹴而就。如果片面強(qiáng)調(diào)測試對實現(xiàn)的驅(qū)動作用,那么實際上隱含了需求和設(shè)計的細(xì)節(jié)可以在實現(xiàn)之前明確下來的假設(shè),這是非常不敏捷的和不現(xiàn)實的!

  Test First要求寫測試用例時對軟件需求有精確的了解,但實際軟件開發(fā)過程中用戶需求和外部環(huán)境的不確定性會導(dǎo)致軟件需求難以把握和頻繁變動。

  用戶需求的不確定性是指需求無法在用戶真正能運行看到效果之前明確下來。比如:讓你開發(fā)一套Wow這樣大型的游戲,你能想象游戲的效果是設(shè)計者一開始就想好了精確到每一個細(xì)節(jié)嗎?對于游戲這樣的軟件,需求和設(shè)計不可能脫離實際運行紙上談兵地產(chǎn)生。游戲的設(shè)計者通常只能借助文檔、草圖、Use Case等非精確的方式大致提出需求,先做出原型,在看到效果之后才能逐步地細(xì)化和明確,需求設(shè)計的增加和改變會伴隨整個軟件開發(fā)過程。

  另外,還有一種極端的情況是根本不存在精確的用戶需求,比如:自動化翻譯軟件,你能在實現(xiàn)之前就把翻譯效果用測試用例固定下來嗎?存在絕對正確的翻譯方法嗎?最近,我們和國外一家大公司客戶談一個項目需求的時候,客戶講了這樣一句話我們現(xiàn)階段還無法提出很細(xì)致的需求,只有等你們拿出第一個版本,然后我們再逐步地調(diào)整細(xì)化。我們的客戶沒有宣稱自己在做敏捷,但人家的思維方式多敏捷啊,不是什么一上來就明確需求,而且還要精確寫出自動化測試用例。有人說這種情況我們?nèi)匀豢梢韵雀鶕?jù)自己的理解進(jìn)行TDD,這樣做可以:

  1. 基于測試用例和客戶溝通明確需求;

  2. 驅(qū)動實現(xiàn)。我對此持不同看法,能執(zhí)行的測試用例和不能執(zhí)行的測試用例有著天壤之別,客戶從測試用例根本無法獲得真實運行的體驗,你能想象蘋果把iPhone的測試用例寫在PPT上,給用戶做一個演講,用戶就能給出關(guān)于iPhone設(shè)計的反饋了嗎?要真正的用戶反饋,就需要實打?qū)嵉能浖?,這不正是敏捷的Working software over document的思想嗎?另外,既然用戶無法在實際體驗之前提出反饋,那么開發(fā)人員在開發(fā)初期做的需求分析和設(shè)計都只是一個探索,隨時可能調(diào)整甚至被推翻,不值得在實現(xiàn)之前進(jìn)行自動化測試設(shè)計的投資。

  外部環(huán)境的不確定性是指"當(dāng)我們的系統(tǒng)需要和外部系統(tǒng)集成時,關(guān)于外部系統(tǒng)行為的假設(shè)也無法在實際集成運行前完全確定"。例如,要做一套股票客戶端連上交易所系統(tǒng),因為交易所的行為會直接影響到客戶端的開發(fā),所以只有在弄清交易所行為的情況下才談得上開發(fā)出高質(zhì)量的客戶端。如果采用測試驅(qū)動,編寫了各種涉及交易所行為的測試用例,比如什么情況下發(fā)什么類型的消息,消息格式如何,如何交互等等,但是這些測試用例本身是否正確卻需要打一個大大的問號!這一方面是由于很多交易所提供的協(xié)議都不夠清晰或者有許多未明確定義的地方;另一方面即使協(xié)議沒有問題,開發(fā)人員也可能由于單純的失誤或者缺乏相應(yīng)領(lǐng)域的基本知識而把協(xié)議理解錯。

  實際上,要真正弄清交易所的行為明確客戶端的需求,最重要的手段還是在交易所提供的測試環(huán)境中跑集成測試。對于Test First來講,測試用例本身的錯誤可以說是代價最大的,不僅浪費時間和精力,更重要的是還打擊開發(fā)人員的士氣,誰愿意來回折騰呢?但很不幸,實際情況是在最初沒有明確交易所行為的時候Test First出來的測試用例隨時可能在真實集成后被推翻,并且如果是比較高層的需求分析失誤,那對整個架構(gòu)設(shè)計來講會是災(zāi)難性的后果。在實際開發(fā)中,我們的軟件需要和其他系統(tǒng)集成的情況是非常普遍的,而期望在沒有進(jìn)行實際集成的情況下弄清外部系統(tǒng)的行為都是不現(xiàn)實和不敏捷的。

  所以,Test First需要對于被測系統(tǒng)的需求和環(huán)境有精確的了解,但由于需求不確定性和外部環(huán)境不確定性兩大問題,Test First在很多時候都是不現(xiàn)實的。其實,Test First和瀑布式思想一脈相承,都強(qiáng)調(diào)需求先于實現(xiàn),而忽略了軟件需求的產(chǎn)生會受到實現(xiàn)的反饋,會在實際運行中不斷調(diào)整探索完善。TDD無非是把需求分析的結(jié)果用測試用例表達(dá),替代傳統(tǒng)用文檔表達(dá)需求,但從宏觀上看,TDD和瀑布比是換湯不換藥,這都不是真正的敏捷。

  除了簡單情況,不存在脫離實現(xiàn)的需求,你能夠在明確了需求之后就實現(xiàn)出一套Linux系統(tǒng)嗎?既然你根本無法實現(xiàn)一套Linux系統(tǒng),那么這樣所謂的需求又有多大的意義呢?所以,能提出什么樣的需求不能脫離你的實現(xiàn)能力。需求和實現(xiàn)之間不是簡單的誰驅(qū)動誰,而是一種相互反饋的關(guān)系,這與需求用什么方式表達(dá)沒有關(guān)系。正如瀑布模型無法在初始階段做出完美的需求分析,TDD也無法在初始階段做出完美的測試用例;不僅如此,自動化測試用例的開發(fā)維護(hù)成本還遠(yuǎn)高于文檔。

  所以,在敏捷環(huán)境中,軟件開發(fā)初期應(yīng)該通過文檔和用例等手段大致表達(dá)需求,實現(xiàn)之后在實際運行中體驗效果,不斷優(yōu)化探索和明確需求和外部環(huán)境,當(dāng)需求和對外部環(huán)境的認(rèn)識達(dá)到一個比較穩(wěn)定的程度才編寫測試用例將需求固化下來。

  上面的論述主要針對貼近最終用戶的外部需求(如ATDD),下面我會進(jìn)一步解釋即使是在內(nèi)部的單元測試級別TDD仍然有問題。我們還是首先從需求入手,思考一下單元的需求是哪里來的呢?答案是:需求來自于設(shè)計!比如,對輪胎的需求來源于汽車的設(shè)計,低層模塊的需求來源于高層模塊的設(shè)計。

  而在開發(fā)初期,這種內(nèi)部設(shè)計具有很大的不穩(wěn)定性,帶有很多假設(shè)的成分,在沒有進(jìn)行集成測試的情況下,很難講這種內(nèi)部設(shè)計是否合理。實際項目開發(fā)通常會在集成運行之后不斷調(diào)整內(nèi)部的設(shè)計,即影響單元的需求。那么,如果是測試驅(qū)動,首先按不成熟的內(nèi)部設(shè)計把一個個單元需求編寫成單元測試再來實現(xiàn),實際上大大推遲了能進(jìn)行集成測試的時間,對于真正快速弄清高層需求穩(wěn)定設(shè)計反而是不利的。

  假設(shè)最終還是所有單元都完成,然后開始運行集成或驗收測試,這時候有兩種可能:

  1. 用戶看到實際效果,決定調(diào)整需求;

  2. 發(fā)現(xiàn)集成前在單元層面的假設(shè)不成立或者是有沒有考慮到的情況。不論是哪一種情況發(fā)生,以前所寫的單元測試都面臨著被廢棄或必須修改的命運。實際上,多數(shù)與業(yè)務(wù)相關(guān)的單元測試用例比起集成或驗收測試用例更加不穩(wěn)定,因為它會受到所有其上層模塊的需求和設(shè)計變動的影響。

  由于我們在不穩(wěn)定的單元測試上浪費了大量的時間(按我的經(jīng)驗編寫單元測試比編寫實現(xiàn)更耗時),這就導(dǎo)致了遲遲無法進(jìn)行集成看到實際效果,也沒有辦法敏捷地應(yīng)對需求的調(diào)整。也就是說具有諷刺意味的,Test First理念居然是和敏捷理念矛盾的!
  所以,我認(rèn)為Test First不符合敏捷開發(fā)的基本假設(shè),而真正符合敏捷的理念是需求和設(shè)計依賴于實現(xiàn)的反饋,需要在實際運行過程中根據(jù)效果不斷探索調(diào)整得來的,不可能脫離實際運行寫出真正符合最終需求的測試用例來。所以,我們真正應(yīng)該做的是盡快看到實際運行的效果,而自動化測試作為固化的需求和設(shè)計是在看到效果之后。在集成之前花太多精力進(jìn)行測試驅(qū)動只會導(dǎo)致遲遲看不到實際運行效果(尤其是基于開發(fā)人員自己的假設(shè)編寫大量單元測試用例),看到效果需要調(diào)整需求又會廢掉或改掉一大堆的測試用例。

  實際上,越是外部的需求其變更帶來的影響和代價越大,越是需要盡早明確。從宏觀上看,TDD所謂的快速反饋實際上是加快內(nèi)部反饋,延遲了外部反饋,這無異于本末倒置。而大量需要修改或作廢的測試用例其實是一種很大的浪費,這和消除浪費的精益思想也是矛盾的!

  上面這幅cost/length_of_feedback_cycle圖是我們常見的用于說明敏捷方法比傳統(tǒng)方法具有更短的反饋周期,更小代價的應(yīng)對變化。從圖中我們可以清晰的看到在驗收測試中發(fā)現(xiàn)的需求錯誤導(dǎo)致的代價是最高的。如果驗收測試往后推遲一點,發(fā)現(xiàn)錯誤的代價將按非線性地增長。上面我們已經(jīng)論述了,任何方法都不可能消除驗收測試后對需求的調(diào)整,因為這是需求產(chǎn)生的正常過程。

  我們唯一可以做的是盡可能地縮短驗收測試的反饋周期,但是很不幸TDD大量的內(nèi)部測試只會導(dǎo)致推遲驗收測試的時間,從而大大增加代價。在實際開發(fā)中,我提倡在第一次集成運行測試之前不要寫單元測試用例;自動化的驗收測試用例則視編寫和維護(hù)的代價而定,如果代價比較高,則應(yīng)該采用文檔和Use Case來描述需求,因為這兩種方式比自動化的驗收測試更容易維護(hù)。編寫單元測試一定是在集成以后,這樣才能首先得到外部反饋,盡量先保證做正確的事情,再正確地做事。

  下面這段話來自于InfoQ文章《Mock不是測試的銀彈》:在使用JMock框架后測試編寫起來更容易,運行速度更快,也更穩(wěn)定,然而出乎意料的是產(chǎn)品質(zhì)量并沒有如我們所預(yù)期的隨著不斷添加 的測試而變得愈加健壯,雖然產(chǎn)品代碼的單元測試覆蓋率超過了80%,然而在發(fā)布前進(jìn)行全面測試時,常常發(fā)現(xiàn)嚴(yán)重的功能缺陷而不得不一輪輪的修復(fù)缺陷、回歸 測試。為什么編寫了大量的測試還會頻繁出現(xiàn)這些問題呢? 這描述的情況和我在實踐中遇到的情況類似,不過很可惜文章并沒有找到問題真正的原因。

it知識庫TDD到底美不美?,轉(zhuǎn)載需保留來源!

鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標(biāo)記有誤,請第一時間聯(lián)系我們修改或刪除,多謝。

主站蜘蛛池模板: 免费观看激烈日板子 | av天堂电影网 | 亚洲 欧美 综合 高清 在线 | 亚洲精品蜜桃AV久久久 | 亚洲精品久久久久久久蜜臀老牛 | 友田真希息与子中文字幕 | 成品片a免人看免费 | 色狠狠色狠狠综合天天 | 使劲别停好大好深好爽动态图 | 北条麻妃快播 | 美女张开腿让男人桶爽无弹窗 | 中文字幕亚洲欧美日韩2019 | 欧美 亚洲综合在线一区 | 日韩精品专区在线影院重磅 | 色就色 综合偷拍区欧美 | 国产午夜免费不卡精品理论片 | 男女作爱在线播放免费网页版观看 | 在线视频一区二区三区在线播放 | 4438全国免费观看 | 国产精品爆乳尤物99精品 | 欧美区 bt | 日本成熟bbxxxxxxxx | 精品一成人岛国片在线观看 | 男人J桶进男人屁股过程 | 久久婷五月综合色啪首页 | 俺来也俺去也视频久久 | java农村野外妇女hd | 丰满老熟女白浆直流 | 亚洲精品AV无码重口另类 | 嗯啊快停下我是你老师啊H 嗯啊快拔出来我是你老师视频 | 久久视频在线视频观品15 | 国内精品久久久久影院老司 | 久久91精品久久久久久水蜜桃 | 久久全国免费久久青青小草 | 久久天天躁狠狠躁夜夜呲 | 午夜AV内射一区二区三区红桃视 | 爱看吧孕妇网 | 国产免费人成在线视频有码 | 久久天堂网 | 最近免费中文字幕完整版HD | 亚洲AV國產国产久青草 |