成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

推行編程利器之一TDD的思考

開發(fā) 開發(fā)工具
本文內(nèi)容是我在某大型團(tuán)隊(duì)中推行TDD時(shí)的一些思考。如今看來(lái),這些思考仍有現(xiàn)實(shí)意義。

[[186765]]

我在參與的開發(fā)項(xiàng)目以及咨詢項(xiàng)目中,都有實(shí)踐TDD的經(jīng)驗(yàn)。直至今日,我仍然會(huì)在某些功能開發(fā)時(shí)采用TDD的方式實(shí)現(xiàn)功能。雖然沒(méi)有達(dá)到將TDD溶于開發(fā)血液之中形成自然而然的習(xí)慣,但至少也是我常用的編程利器之一,偶爾使用,效果還算不錯(cuò)。

以下內(nèi)容則是我在某大型團(tuán)隊(duì)中推行TDD時(shí)的一些思考。當(dāng)時(shí)的整個(gè)咨詢過(guò)程,至少在TDD推行上可以稱得上是舉步維艱。如今看來(lái),這些思考仍有現(xiàn)實(shí)意義。

1. 開發(fā)人員的質(zhì)量意識(shí)

開發(fā)人員包括管理人員的軟件質(zhì)量意識(shí),常常立足于清晰可見的外部質(zhì)量。評(píng)價(jià)一個(gè)開發(fā)人員的績(jī)效,很重要的一個(gè)指標(biāo)就是被測(cè)試人員發(fā)現(xiàn)的缺陷數(shù)。

慣常的軟件開發(fā)思想,總是認(rèn)為開發(fā)人員不適合做測(cè)試,因?yàn)樗麄兛偸钦驹谧约旱慕嵌热タ创龁?wèn)題,從而可能忽略真正需要測(cè)試的用例。這種思想給了開發(fā)人員一個(gè)錯(cuò)誤信號(hào),認(rèn)為自己不應(yīng)該寫測(cè)試,即使寫了測(cè)試,也寫不好。

殊不知,由開發(fā)人員編寫測(cè)試帶來(lái)的收益,最重要的一點(diǎn)不在于測(cè)試本身,而在于它能促進(jìn)開發(fā)、測(cè)試以及需求分析人員的交流與溝通。而測(cè)試先行的方式也能讓開發(fā)者跳出實(shí)現(xiàn)的窠臼,而從業(yè)務(wù)角度去看待問(wèn)題,從消費(fèi)者角度去思考接口的設(shè)計(jì)。

倘若開發(fā)者總是憊懶地將測(cè)試職責(zé)委派給專門的測(cè)試人員,漸漸地,就會(huì)滋生一種依賴心理。測(cè)試人員的精確測(cè)試當(dāng)然可以保障質(zhì)量,但這種測(cè)試通常是黑盒測(cè)試,這里保障的質(zhì)量主要還是外部質(zhì)量。而且,這種測(cè)試帶來(lái)的反饋總是慢于開發(fā)進(jìn)度,一旦發(fā)現(xiàn)缺陷,修復(fù)缺陷的成本也會(huì)變得更高。

軟件質(zhì)量除了外部質(zhì)量之外,內(nèi)部質(zhì)量同等重要。

軟件成本等于開發(fā)成本與維護(hù)成本之和,而維護(hù)成本的增加主要?dú)w咎于內(nèi)部質(zhì)量的糟糕。

當(dāng)我們讓開發(fā)人員為原有代碼編寫單元測(cè)試時(shí),總是覺得舉步維艱,主因就在于代碼的可測(cè)試性不夠好。要測(cè)試一個(gè)類,竟然連簡(jiǎn)單創(chuàng)建它的對(duì)象都變成了不可能完成的任務(wù)。在為這樣的代碼編寫單元測(cè)試時(shí),就好像被落到了蜘蛛網(wǎng)中,被這些網(wǎng)絲牽住,纏住,如何掙扎都無(wú)法擺脫;除非,我們能夠快刀斬亂麻。然而,一旦采用這種粗暴的方式,則對(duì)于系統(tǒng)而言,就不是維護(hù),而是重寫了。

測(cè)試先行的開發(fā)至少在一定程度規(guī)避了這樣的問(wèn)題。因?yàn)殚_發(fā)人員首先要寫好測(cè)試,這就驅(qū)使開發(fā)人員必須強(qiáng)制地思考代碼的可測(cè)試性。而在足夠多的測(cè)試保護(hù)下,即使代碼的內(nèi)部質(zhì)量欠佳,要進(jìn)行重構(gòu)也更為簡(jiǎn)單。

然而,這些好處都不是短期能見成效的,且團(tuán)隊(duì)若不能達(dá)成共識(shí),只靠一二人堅(jiān)定地踐行TDD,在測(cè)試覆蓋率不夠的情況下,無(wú)異于杯水車薪。多數(shù)開發(fā)者在維護(hù)別人的丑陋代碼時(shí),可能會(huì)罵聲連連,殊不知同時(shí)作為罵者自身,其實(shí)也在重復(fù)被罵者的故事。

2. 需求分析與任務(wù)分解

需求分析能力常常是開發(fā)人員的短板。開發(fā)人員養(yǎng)成了一個(gè)習(xí)慣,看什么事情都會(huì)從技術(shù)實(shí)現(xiàn)的角度去思考。要實(shí)現(xiàn)一個(gè)網(wǎng)頁(yè),就會(huì)想到如何編寫JavaScript來(lái)響應(yīng)用戶的動(dòng)作,如何編寫CSS,卻很少思考用戶體驗(yàn)和操作的流程。要完成一個(gè)數(shù)據(jù)分析,總會(huì)想到數(shù)據(jù)的屬性,轉(zhuǎn)換和提取數(shù)據(jù)的算法,卻不會(huì)想到分析數(shù)據(jù)的價(jià)值以及合理的流程。

對(duì)于繁瑣的需求描述,我們總是沒(méi)有耐心去深入研讀,而是在掌握了大體意思后,就開始匆匆進(jìn)行開發(fā)與實(shí)現(xiàn)。TDD要求我們?cè)诰帉憸y(cè)試之前要做好合理的任務(wù)分解。若沒(méi)有很好地理解需求,任務(wù)分解就無(wú)法順利進(jìn)行。

這就帶來(lái)了團(tuán)隊(duì)協(xié)作的問(wèn)題。

若我們能從需求的源頭進(jìn)行改進(jìn),或許TDD會(huì)變得更容易。例如,對(duì)故事的拆分更合理,遵循User Story的INVEST原則,那么,要實(shí)現(xiàn)的Story在測(cè)試性、獨(dú)立性方面就會(huì)有更好的改觀。如果需求分析人員能夠非常明確地編寫出驗(yàn)收標(biāo)準(zhǔn)(Acceptance Cretiria),任務(wù)分解也會(huì)變得更加容易。

更進(jìn)一步,若需求分析人員能夠參考甚至遵循Specification By Example的方式,采用Given-When-Then的模式來(lái)描繪各個(gè)用例場(chǎng)景;那么,再要進(jìn)行任務(wù)分解,不就變得輕而易舉嗎?所以說(shuō),推行TDD之所以非常艱難,或許***的原因是我們僅僅將目光放到了開發(fā)者身上,卻忽略了需求分析人員扮演的關(guān)鍵角色。正所謂:“問(wèn)渠那得清如許,為有源頭活水來(lái)。”

我一直強(qiáng)調(diào)任務(wù)分解是有層次的。分析需求時(shí),不能一個(gè)猛子就扎進(jìn)繁瑣的實(shí)現(xiàn)細(xì)節(jié)。要從用戶價(jià)值出發(fā),先梳理出最外層的需求任務(wù),然后抽絲剝繭,條分縷析地層層遞進(jìn),如此方能理清思路,掌控復(fù)雜邏輯。基本上,任務(wù)分解可以分為三個(gè)層次,即業(yè)務(wù)價(jià)值——>業(yè)務(wù)功能——>業(yè)務(wù)實(shí)現(xiàn)。這個(gè)層次是一種“遞歸”的狀態(tài),視需求的復(fù)雜度可以不停向下拆分。

任務(wù)分解是TDD的核心,是驅(qū)動(dòng)設(shè)計(jì)和開發(fā)的重要力量,卻被很多人忽略了。不能不說(shuō)是一種誤解與遺憾。

3. 測(cè)試先行的編程習(xí)慣

正所謂“江山易改本性難移”,數(shù)年養(yǎng)成的開發(fā)習(xí)慣不可能一朝一夕改變。這恰恰成為許多人反對(duì)TDD的借口,鑄造了一塊堅(jiān)硬的用于防守的盾。

然而,以我個(gè)人經(jīng)驗(yàn)以及我所觀察到的情況來(lái)看,這其中固然有習(xí)慣的力量作祟,然而主因還是因?yàn)閷?duì)TDD方法的掌握程度以及一些誤解導(dǎo)致。

前面已經(jīng)述及,任務(wù)分解應(yīng)該是TDD的起點(diǎn)。多數(shù)開發(fā)者未能形成任務(wù)分解的習(xí)慣。因此在改變?yōu)闇y(cè)試先行的時(shí)候,錯(cuò)以為應(yīng)該一上來(lái)就寫測(cè)試。因?yàn)樗悸窙](méi)有理清,腦子里一片亂麻,再加上本身對(duì)TDD不夠熟悉,編寫測(cè)試就變得舉步維艱,總覺得束手束腳,就好像被綁了一只手,又好像是在泥沼中掙扎。許多時(shí)候,甚至發(fā)揮不出自己哪怕三分的功力。

一貫以來(lái),我們都在強(qiáng)調(diào)測(cè)試先行。這容易產(chǎn)生一種錯(cuò)覺,就是認(rèn)為TDD必須一開始就寫測(cè)試,“簡(jiǎn)單設(shè)計(jì)”嘛,于是就沒(méi)有了設(shè)計(jì)。這讓那些習(xí)慣于事先設(shè)計(jì)的開發(fā)者更難以接受。

那么,TDD是否需要事先設(shè)計(jì)呢?Martin Fowler的文章Is Design Dead其實(shí)就是對(duì)此問(wèn)題的正本清源。我個(gè)人認(rèn)為,視場(chǎng)景而定,測(cè)試驅(qū)動(dòng)開發(fā)仍可進(jìn)行事先設(shè)計(jì)。

設(shè)計(jì)并不僅包含技術(shù)層面的設(shè)計(jì)如對(duì)OO思想乃至設(shè)計(jì)模式的運(yùn)用,它本身還包括對(duì)需求的分析與建模。若不分析需求就開始編寫測(cè)試,就好像沒(méi)有搞清楚要去的地方,就開始快步前行,***才發(fā)現(xiàn)南轅北轍一般。

測(cè)試驅(qū)動(dòng)開發(fā)提倡的任務(wù)分解,實(shí)際上就是一種需求的分析。如何尋找職責(zé),以及識(shí)別職責(zé)的承擔(dān)者則可以視為建模設(shè)計(jì)。

測(cè)試驅(qū)動(dòng)像是一種培養(yǎng)設(shè)計(jì)專注力的手段,就像冥想者通過(guò)盤腿靜坐的手段來(lái)體悟天地一樣,測(cè)試驅(qū)動(dòng)可以強(qiáng)迫你站在測(cè)試的角度(就是使用者的角度)去思考接口,如此才能設(shè)計(jì)出表現(xiàn)意圖的接口。

在開始測(cè)試驅(qū)動(dòng)開發(fā)之前,做適度的事先設(shè)計(jì),還有利于我們仔細(xì)思考技術(shù)實(shí)現(xiàn)的解決方案。它與測(cè)試驅(qū)動(dòng)接口的設(shè)計(jì)并不相悖。解決方案或許屬于實(shí)現(xiàn)層面,若過(guò)早思考實(shí)現(xiàn),會(huì)干擾我們對(duì)接口的判斷;但完全不理會(huì)實(shí)現(xiàn),又可能導(dǎo)致設(shè)計(jì)方向的走偏。

例如,我們要實(shí)現(xiàn)XML消息到Java對(duì)象的轉(zhuǎn)換。

一種解決方案是通過(guò)jaxb將消息轉(zhuǎn)換為Java對(duì)象,然后再定義轉(zhuǎn)換映射的Transformer,通過(guò)硬編碼或者反射的方式將其轉(zhuǎn)換為相關(guān)的領(lǐng)域?qū)ο?然后在執(zhí)行了業(yè)務(wù)操作后,再將返回的結(jié)果轉(zhuǎn)換為另一個(gè)Jaxb對(duì)象。另一種解決方案則是通過(guò)引入模板,例如StringTemplate或者Velocity,定義轉(zhuǎn)換的模板,然后進(jìn)行替換實(shí)現(xiàn)。這兩種解決方案的區(qū)別,直接影響了我們劃分任務(wù)的方式。

所以,在運(yùn)用TDD時(shí),先不要一巴掌拍死,可以先抱著開放的態(tài)度嘗試嘗試。何況,TDD并非一招鮮,吃遍天,總要有適合它的場(chǎng)景。例如UI的開發(fā),交互協(xié)作的控制邏輯,數(shù)據(jù)庫(kù)開發(fā),并發(fā)處理,都不是運(yùn)用TDD的好場(chǎng)景。

4. 重構(gòu)能力

TDD的核心是紅——綠——重構(gòu)。這意味著重構(gòu)是TDD非常重要的一環(huán),它直接關(guān)系到TDD開發(fā)出來(lái)的代碼質(zhì)量。沒(méi)有好的重構(gòu)能力,TDD就會(huì)有缺失。若說(shuō)代碼的內(nèi)部質(zhì)量是生命的話,重構(gòu)就是靈魂,缺少了它,代碼就沒(méi)有靈性了。多數(shù)時(shí)候?qū)嵤㏕DD,都會(huì)因?yàn)橹貥?gòu)能力的缺乏而陷入困境。

重構(gòu)的關(guān)鍵首先在于如何識(shí)別代碼的壞味道。這需要代碼閱讀的千錘百煉,而非死記硬背Martin Fowler在《重構(gòu)》一書中總結(jié)的壞味道。當(dāng)這些壞味道變成你的一種直覺,甚至就像與生俱來(lái)的一種能力時(shí),你就會(huì)降低對(duì)糟糕代碼的容忍度。在你眼中,這些爛代碼就是垃圾,必須清掃,否則無(wú)法“安居”。

重構(gòu)手法與代碼壞味道一一對(duì)應(yīng)。若有測(cè)試保障,重構(gòu)就變得安全。但盡可能地,我們還是希望運(yùn)用工具提供的自動(dòng)重構(gòu)功能,這既提高了重構(gòu)效率,也在一定程度下確保了重構(gòu)的安全。

當(dāng)然,重要的是要找到重構(gòu)的節(jié)奏感,即小步前行,每次重構(gòu)必運(yùn)行測(cè)試的良好習(xí)慣。若能結(jié)合分布式版本管理系統(tǒng)如Git,做到原子提交,就會(huì)更加方便。即使重構(gòu)出現(xiàn)問(wèn)題,也可以快速地回到前面的版本快照。

在TDD過(guò)程中,若能結(jié)對(duì)自然是上佳選擇。當(dāng)一個(gè)人在掌控鍵盤時(shí),另一個(gè)人就可以重點(diǎn)關(guān)注代碼的可讀性,看看代碼是否散發(fā)出臭味。兩個(gè)人的眼睛終歸要更銳利一些,至少視野的范圍更廣泛。

及時(shí)重構(gòu)是重構(gòu)諸多實(shí)踐中最重要的一點(diǎn)。不要讓重構(gòu)成為你在未來(lái)償還債務(wù)的殺手锏。越拖到后面,償還債務(wù)的成本就越高。以重構(gòu)而論,如果將重構(gòu)拖到***,則需要的重構(gòu)能力就更強(qiáng),因?yàn)槌绦蚪Y(jié)構(gòu)會(huì)變得更復(fù)雜。當(dāng)然,只要你的代碼能夠保證足夠的覆蓋率,以及較好的松散耦合,重構(gòu)依舊可行。采用TDD,基本能滿足這兩條要求。但以成本而論,小步前行才是重構(gòu)之道。

5. 單元測(cè)試的基礎(chǔ)設(shè)施

***說(shuō)說(shuō)單元測(cè)試的基本設(shè)施。很多時(shí)候,這可能不是問(wèn)題;但很多時(shí)候,這可能會(huì)成為大問(wèn)題。面對(duì)諸如測(cè)試數(shù)據(jù)準(zhǔn)備等問(wèn)題,需要認(rèn)真分析,找到應(yīng)對(duì)方案。

原則上,***能找到一些開源的測(cè)試框架,包括生成測(cè)試數(shù)據(jù),模擬測(cè)試行為等。因?yàn)槟阌龅降膯?wèn)題,別人可能早已遇見過(guò)。這個(gè)世界上有很多聰明而又樂(lè)于分享的程序員,不要局限在自己公司一隅。睜大眼睛看看滿世界吧。所謂“君子生非異也,善假于物也”。好程序員,也要這樣。

 說(shuō)不定,你會(huì)拋棄TDD,因?yàn)槟阏业搅烁玫倪m合你的做法。

【本文為51CTO專欄作者“張逸”原創(chuàng)稿件,轉(zhuǎn)載請(qǐng)聯(lián)系原作者】

戳這里,看該作者更多好文

責(zé)任編輯:趙寧寧 來(lái)源: 51CTO專欄
相關(guān)推薦

2021-10-30 18:38:49

Java c++反射

2020-06-09 14:30:17

編程命名代碼

2013-11-11 09:26:50

編程思考

2021-07-07 09:18:00

Java并發(fā)編程

2009-09-24 09:41:00

Scala講座Scala

2013-09-12 15:51:04

編程文化垃圾代碼移動(dòng)開發(fā)

2021-06-06 16:56:49

異步編程Completable

2009-10-23 13:24:20

linux Shell

2017-03-16 13:17:54

TDD代碼開發(fā)

2013-04-18 09:29:02

編程語(yǔ)言編程

2024-04-18 08:20:27

Java 8編程工具

2015-11-24 16:59:13

2021-06-15 07:10:14

JavaScript異步編程

2014-03-03 09:48:55

SSHTmux

2022-10-19 11:31:49

TDD開發(fā)

2011-07-21 14:17:15

Ceylon

2014-03-07 11:32:18

2023-06-27 08:37:35

Java反射動(dòng)態(tài)代理機(jī)制

2024-12-27 09:08:25

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 欧美精品一区在线 | 一区二区三区久久 | 九九在线 | 亚洲 成人 在线 | 日韩在线看片 | 在线中文字幕国产 | 人人干人人干人人干 | 精品毛片 | 中文字幕高清 | 欧美不卡一区二区 | 国产综合久久久久久鬼色 | 国产精品片aa在线观看 | 亚洲成人中文字幕 | 2021狠狠天天天 | 日韩欧美视频 | 国产成人艳妇aa视频在线 | 国产精品成人在线观看 | 日本一区二区在线视频 | 精品一区二区三区在线观看 | 日韩av免费看 | 五月天国产视频 | 一区二区在线 | 免费av电影网站 | 欧美日韩国产免费 | 国产三级国产精品 | 久久久九九 | 欧美久久一区二区三区 | 欧美黄色一区 | 国产91综合一区在线观看 | 一区二区不卡视频 | 91免费观看视频 | 欧美精品欧美精品系列 | k8久久久一区二区三区 | 色婷婷久久久久swag精品 | 国产网站在线免费观看 | 国产福利视频网站 | 欧美一区在线看 | 久视频在线观看 | 中文字幕国产一区 | 精品二区 | 免费看爱爱视频 |