任務(wù)分解:
??找到實現(xiàn)路徑 ??學(xué)習(xí)經(jīng)驗,收集錯誤/痛點/風(fēng)險點
??將大目標(biāo)拆分成可執(zhí)行任務(wù)序列。
檢驗標(biāo)準(zhǔn):是否清晰知道如何行動。知道自己下一步要做什么,優(yōu)先級-應(yīng)對插入打斷,需要哪些資源,有什么風(fēng)險-什么時候能消除這部分不確定性,制定可完成的計劃時間表。
??:小 ?可以隨時停下來 try粒度在1~3個番茄之間
??:分而治之
開發(fā):feature -> user story -> task
#隨著軟件開發(fā),軟件變更成本在逐步增加
????測試金字塔:
??:越是底層越多測試
??:多寫單元測試
在本地運行單元測試和集成測試,在持續(xù)集成服務(wù)器上運行系統(tǒng)測試
mvc結(jié)構(gòu)的工程,c層的單元測試要實際的去調(diào)用m層嗎?需要和數(shù)據(jù)庫里的數(shù)據(jù)做比對和驗證嗎?如果不用,c層的單元測試應(yīng)該驗證或測試哪些內(nèi)容呢?
作者回復(fù): 在單元測試?yán)?,M 的接口是可以用 Mock 的,這才算是單元測試。涉及到數(shù)據(jù)庫,就變成了集成測試。
測試驅(qū)動開發(fā)TDD(Test Driven Development/Design)
??≠ 測試先行開發(fā)(先寫測試后可代碼)。區(qū)別在于重構(gòu)。
思維上的轉(zhuǎn)變:編寫可測的代碼
開發(fā)守則:
盡量不寫 static 方法。
除非它不涉及任何狀態(tài)&&行為簡單,如可以抽象出來做庫函數(shù)的程度。
if 第三方的static,將其封裝
主分支開發(fā)模型是一種更好的開發(fā)分支模型
極限編程:
思想:把好的實踐推向極限
實踐:TDD、持續(xù)集成、結(jié)對編程、現(xiàn)場客戶……
最佳實踐是,基于主分支的模型。大家都在同一個分支上進行開發(fā)
一個是在已用線上產(chǎn)品的時候,我們通常會有一條release分支。這樣當(dāng)有線上bug出現(xiàn)的時候,我們能在release分支上快速修復(fù) + 上線。
另外一個是,在規(guī)律性的迭代上線時,難免會遇到有story沒有完成(開發(fā)或者測試),此時,就得使用feature toggle 或者 revert代碼了。
最后是當(dāng)在做一個很明顯上線前不可能完成的大feature的時候,一般我們會啟另一條分支來開發(fā)。此時會定時從主分支merge代碼,因為有些改動可能會影響已用的業(yè)務(wù)
主分支開發(fā)模型 遭遇 多個功能同時開發(fā):
Feature Toggle:通過開關(guān),決定哪個功能對外是可用的。//應(yīng)該是一個非常臨時的存在。除非在遺留系統(tǒng)上工作,功能要跨越很長周期。
[]https://martinfowler.com/articles/feature-toggles.html
[]https://www.infoq.cn/article/function-switch-realize-better-continuous-implementations
Branch by Abstraction:在動手改造前,先提取出來一個抽象,把原先的實現(xiàn)變成這個抽象的一個實現(xiàn)。改造的過程就是提供這個抽象的一個新實現(xiàn)。
?在一個分支上進行
?對設(shè)計能力有一定要求。對很多團隊來說,這是一個挑戰(zhàn)。
寫出思路、需要用到的知識點,api等,寫出各個小任務(wù),然后對應(yīng)寫出關(guān)鍵代碼段。
開發(fā)實踐中注意:
數(shù)據(jù)庫遷移別忘記
把需求分解到具體的方法和目標(biāo):
領(lǐng)域?qū)ο?這里就是用戶
數(shù)據(jù)訪問層,在不同的項目里面叫法不一,有人從J2EE年代繼承下來叫DAO(數(shù)據(jù)訪問對象,Data Access Obejct),有人跟著Mybatis 叫 mapper,我現(xiàn)在更傾向于使用領(lǐng)域驅(qū)動設(shè)計的術(shù)語,叫 repository
服務(wù)層,提供對外的應(yīng)用服務(wù),完成業(yè)務(wù)處理
資源層,提供API接口,包括外部請求的合法性檢查
考慮分布式服務(wù)器
訪問控制:
調(diào)整依賴關(guān)系,按需求的完整實現(xiàn)來寫,而非一個一個類
根據(jù)現(xiàn)狀制定改進路徑,不要想著一步到位
分解不了解的技術(shù)任務(wù):
做一次技術(shù)spike,先將它變成熟悉的技術(shù)?#??發(fā)散
? ? 0. ?通過各種渠道(新聞網(wǎng)站、技術(shù)blog、上級安排……)對要使用的技術(shù)有感性的認(rèn)識,知道他是干啥的。
快速完成教程上的例子 (4-5h)
確定這項技術(shù)在項目中應(yīng)用場景和我們的關(guān)注點。
//??spike沒有那么多時間通讀文檔?。。∫槍ψ钪匾膱鼍斑x出幾個最需要的功能。
??要找準(zhǔn)關(guān)注點。比如,采用新的緩存中間件是為了提高性能,那關(guān)注點就是性能,采用新的消息隊列是為了提升吞吐,那關(guān)注點就是吞吐。我們選用一項新技術(shù)總是有自己的一些假設(shè),但這些假設(shè)真的成立嗎?這是我們需要驗證的
驗證想法,決定是否采納這項技術(shù)。
????假如確定使用,丟棄原型重新設(shè)計????
怎么把新技術(shù)用在自己的項目中?
思考這個問題重點要放在“自己的項目”而不是新技術(shù)。
不要混淆目標(biāo)與現(xiàn)狀:
【目標(biāo)】應(yīng)該怎么做
【現(xiàn)狀】正在怎么做
??忙是不去思考改進的借口。假如不忙了,你知道該怎么改進嗎??!
以測試為例:
??業(yè)務(wù)代碼100%測試覆蓋
任務(wù)分解:
與人溝通:
??與團隊達成共識
??將最佳實踐及背后的邏輯與之溝通,講清Why,觸發(fā)動機
自動化:
把測試覆蓋率檢查加入工程,得到現(xiàn)有的測試覆蓋率
將測試覆蓋率加入持續(xù)集成,設(shè)定當(dāng)前測試覆蓋率為初始值。測試覆蓋率不達標(biāo),不許提交代碼。
每周將測試覆蓋率調(diào)高,比如:5%或10%,直到測試覆蓋率達到100%
需求管理:
??口頭不算,全部文件郵件確認(rèn),存檔。
區(qū)分優(yōu)先級,盡可能把精力放在重要的事情上。 站在老板面前講道理
//艾森豪威爾矩陣(Eisenhower Matrix)
??告訴老板:我資源有限,需要將這兩個需求排個序,看哪個更重要。我的上下文有限,需要你幫我判斷一下
老板會和你說這起兩個需求的起源:
擴展盈利的需求是競爭對手都已經(jīng)有了客戶也問這邊要,再不做會影響客戶關(guān)系,尤其是新財年快到了,下個階段的合同會受到影響。
而另外的新業(yè)務(wù)是某天一個高端聚會上得到的新啟發(fā),想嘗試一下,他也不確定這個想法能帶來多少收益,就讓產(chǎn)品部門試一下
????可視化團隊四象限:
為了適當(dāng)減少每次argue需求優(yōu)先級帶來的溝通成本,還可以把當(dāng)前團隊正在面對的四象限公示出來,讓大家都能看到團隊路線圖,讓提需求的人(產(chǎn)品經(jīng)理更需要)看看自己的需求在哪個象限,什么優(yōu)先級,有時候他們自己就明白了
需求分解:
一般用戶故事經(jīng)兩次拆分,先是業(yè)務(wù),再是估算時拆小它。
??用戶登錄是一個master story,可以拆分成第三方驗證,郵箱地址驗證,登錄驗證碼……
好的細(xì)分需求的衡量標(biāo)準(zhǔn):INVEST原則
Independent 獨立性:一個用戶故事完成一個獨立的功能,如果有依賴,將該部分拆出來,重新調(diào)整 //2019/4/28 其實依賴那里沒有看懂,抽出來不還是要依賴嗎?是開發(fā)依賴還是業(yè)務(wù)依賴
Negotiable 可協(xié)商性:主動提問理清需求
??需求管理中印象最深的是剛進入開發(fā)行業(yè)時的一段經(jīng)歷。當(dāng)時要顯現(xiàn)某種單據(jù),單據(jù)本身還嵌套子單據(jù),原始需求是單據(jù)按層次顯示,但某變量等于某個值時,某層次的單據(jù)就隱藏,但它的再下一層子單據(jù)需要顯示。解決方案簡單可以理解成頁面要用遞歸方式才能正確顯示。當(dāng)時一心想顯示自己牛鼻,因為無法用通常的頁面模版機制,就自己寫工具遞歸生成頁面代碼,看起來代碼很巧妙,但別人難以維護。后來有段小插曲,若干年后項目移交到另外一個研發(fā)中心時,還需要有人專門去講這段代碼,否則接手人很難理解。再說回到之前,開發(fā)完后有一次和業(yè)務(wù)分析員再次聊起,說這個很不好實現(xiàn)但我啃下來了等等,他說那可以不用隱藏,顯示空白層也可以,真如果這樣實現(xiàn)就簡單多了,也好理解多了。事不大,但在職業(yè)生涯里印象深刻。需求不光是拆解,更可以討論后尋找簡單解決方案,而不是用自以為牛鼻的代碼實現(xiàn)。以更合理的成本實現(xiàn)需求交付價值,這其實是用戶故事里Negotiable的意義所在
Valuable 有價值的:
這個功能不做,用戶會怎樣?有沒有什么替代方案。
Estimatable 可估算的:
假如不能估算,要么因為還有很多不確定因素,要么因為需求還是太大,都沒到可開發(fā)的狀態(tài)。
??How:分解好用戶故事之后從中挑出最簡單的作為基準(zhǔn),其他任務(wù)清單和它相比的復(fù)雜度給個估計。
假如大家估算差異過大,是因為對需求的理解出現(xiàn)了巨大的差異。
Small ?。盒〔欧奖阏{(diào)度和安排工作
Testable 可測試的
面對不確定的產(chǎn)品:最小可行產(chǎn)品(Minimum Viable Product,MVP)
??最小的代價:
??:能不做就不做,能簡化就簡化
??我們要做的是驗證一個想法的可行性,甚至不是為了開發(fā)一個軟件,不要把解決方案當(dāng)作問題。
??想做物聯(lián)網(wǎng)相關(guān)項目:
做產(chǎn)品文檔,讓銷售拿給用戶看。? 驗證已有設(shè)備進行物聯(lián)網(wǎng)改造的需求確實存在。額外收獲:知道客戶能接受的價格區(qū)間
用原型工具做界面和產(chǎn)品交互,用戶可以實際體驗?根據(jù)用戶真實反饋,調(diào)整產(chǎn)品設(shè)計
整理反饋,決定哪些可以真正開發(fā)出來,進入開發(fā)階段
可行的路徑:
??:可行不是模塊多么完整,而是用戶路徑是否暢通
??:P2P項目(個人對個人互聯(lián)網(wǎng)借貸平臺),項目方希望盡快上線:
#當(dāng)時間有限時,我們需要學(xué)會找到一條可行的路徑,在完整用戶體驗和完整系統(tǒng)之間,找到一個平衡。
業(yè)務(wù)模型:貸款方貸款之后,一次性拿到所有的錢,然后用等額本息的方式每個月還款,最后一個月剩多少錢一次性全還了。
第一次上線,1個月后?只做最基本的還是不夠時間?第一版只包含貸款能力
兩周一迭代,一個半月后上線了每期等額本息還款。
基礎(chǔ)上慢慢疊加,但用戶發(fā)現(xiàn)不了,它的視角始終是個完整的平臺
總的來說,小步快跑。先弄清客戶想要什么,整理后再用自己的語言復(fù)述一遍,后面拿著原型+業(yè)務(wù)交互給客戶確認(rèn),同時把自己的設(shè)計理念植入進去和客戶探討,有些點對方之前也沒有想清楚,尤其是實現(xiàn)方面需要專業(yè)的軟件意見去參考,而我們再從探討中更新自己的認(rèn)知,如此往復(fù)幾次,大方向上就不會有偏差,后面在實施過程中再局部調(diào)整。尤其是對于不確定性很高或者從零開始的工作,這是個可操作的方式。
測試:
階段:
前置準(zhǔn)備:準(zhǔn)備依賴 e.g:組件(使用mock隔離)、參數(shù)
??執(zhí)行:一般就一行代碼的調(diào)用
斷言:我們的預(yù)期,就是這段代碼執(zhí)行出來怎么算是對的 //不只是assert,mock框架的verify
清理: 釋放資源 //利用好現(xiàn)有的測試基礎(chǔ)設(shè)施(比如,JUnit 的 Rule),遵循好測試規(guī)范的話,很多情況下,這個部分就會省掉了。
??A-TRIP:
Automatic,自動化:盡可能交給機器,人工參與越少越好。
Thorough,全面的:
寫代碼前:考慮各種場景:正常的、異常的、各種邊界條件
代碼寫好后:看測試是否覆蓋了所有的代碼和所有的分支
if在補測試,讓測試覆蓋率逐步提升是個好方法
Repeatable,可重復(fù)的:
反復(fù)運行結(jié)果應(yīng)相同
測試本身不依賴于任何不再控制下的環(huán)境:
外部依賴?模擬服務(wù)???Moco:模擬外部HTTP服務(wù)
依賴數(shù)據(jù)庫?測試完后回滾數(shù)據(jù)庫 ??SpringBoot@Transactional
CI的數(shù)據(jù)庫是共用的,沒有本地的那份初始化數(shù)據(jù)集
?保持?jǐn)?shù)據(jù)庫干凈,用測試時用初始化腳本準(zhǔn)備數(shù)據(jù)
?如果測的場景比較復(fù)雜,比如要測多個事務(wù)的交互結(jié)果,還可以引入Docker,將依賴的數(shù)據(jù)庫及初始化數(shù)據(jù)做成Docker的image,測試代碼就更加簡單,并且可以重復(fù)運行了,只要CI支持Docker即可
測試代碼中盡量避免與數(shù)據(jù)庫打交道,測試更關(guān)注領(lǐng)域與業(yè)務(wù),往往爆雷更多的是resource和service,模型的變化往往牽動著表結(jié)構(gòu)的變化,與其兩頭兼顧不如多聚焦模型,我常用的做法是用例配合若干小文件(數(shù)據(jù)忠實于模型),保證庫操作臨門一腳前所有環(huán)節(jié)都是正確的,同時方便適應(yīng)變化。一旦出現(xiàn)異常,也比較容易定位是否是數(shù)據(jù)庫操作引發(fā)的問題。(此點基于工作中發(fā)現(xiàn)項目型程序員大多是先急于把表結(jié)構(gòu)定義出來,好像不這么做寫代碼就不踏實) //2019/4/27 雖然沒太看懂
Independent,獨立的:測試不相互依賴?
if多個測試有相同的準(zhǔn)備和清理?use setup & teardown?
Professional,專業(yè)的:按代碼的標(biāo)準(zhǔn)維護
比如:良好的命名,把函數(shù)寫小,要重構(gòu),甚至要抽象出測試的基礎(chǔ)庫,?? Web 測試中常見的 PageObject 模式
????簡單到一目了然,不需要證明它的正確性
????:
一個測試做很多事。??出現(xiàn)了幾個不同的方法的調(diào)用 ?拆分成幾個測試
沒有斷言 Hmm……
復(fù)雜 ??出現(xiàn)判斷/循環(huán)語句?判斷 拆分 每個測試覆蓋一種場景 | 循環(huán) 測試等價類->用少量數(shù)據(jù)