【读书笔记】-《软件测试的艺术》
2018年10月13日23:24:26
自詡:
? ? ? ? 因為上一東家工作的原因而接觸測試。原本本職是嵌入式軟件,因為公司正在風(fēng)口浪尖的階段,就是一種小公司要發(fā)展成為大公司而經(jīng)歷的那種痛,全公司上下都忙得焦頭爛額的這樣的背景下,我從軟件變成了“測試”小組組長。當(dāng)時的心情既興奮又擔(dān)心。興奮是因為自己一年的努力與突出表現(xiàn),老板看在眼里,從而相信我有這個能力去接這個職位。現(xiàn)在想起來,也確實(shí)是,老板不會看錯人,不會隨便將一個人放在一個新建部門小組組長的職位上。但是我卻時隔了4個月,離職了4個月后才深深的體會到,是真的是個非常好的機(jī)會,回想起來還是非常感謝公司的培養(yǎng)。現(xiàn)在的工作不會像之前那樣,幾乎是華為蘋果公司的強(qiáng)度,至少對我來說,我是18小時在線狀態(tài),隨時相應(yīng)蘋果客戶的測試問題。這也是一個讓我不自信的原因,害怕自己做不好讓公司利益受損。但是現(xiàn)在想想還真是慶幸,我熬過了半年,壓力迫使我現(xiàn)在處事更加從容,再復(fù)雜的問題都有始有終,總能找到一個合理的解決方法。也正是因為太忙,讓一個剛剛畢業(yè)的我遇上了,我想擠點(diǎn)時間讓自己充電,讓自己沉淀,讓自己多一些開發(fā)經(jīng)驗,這樣我才有底氣去領(lǐng)導(dǎo)一個小組,這是我離職的最主要原因。所以我現(xiàn)在才有些時間在這里巴拉巴拉這些話。
? ? ? ? 再回到正題,雖然已經(jīng)離職,但也想為自己的工作,新接觸的領(lǐng)域做一個總結(jié),所以才接觸到這本書《軟件測試的藝術(shù)》。我很慶幸我在這本書中,找到我工作時的所使用方法,也讓我一下子對這本書產(chǎn)生了好感,也對我上一家公司我的直屬領(lǐng)導(dǎo)更加欽佩。本書講解的方法都很規(guī)范,真正完全按照執(zhí)行,那將是華為、阿里那樣的大公司所能駕馭的。當(dāng)然,很多公司不需要完完全全按照上面的經(jīng)驗去做,我們只需要找到哪怕一點(diǎn)用在我們現(xiàn)在所屬的公司里,我覺得就足以提高開發(fā)的質(zhì)量。下面就我將來可能會用到的一些方法進(jìn)行總結(jié),當(dāng)然書上還有更加高級的測試?yán)碚?#xff0c;因為個人理解有限,不敢曲解書面意思。
? ? ? ? 中國的測試工程師是應(yīng)屆畢業(yè)生就可以去“勝任”的;而外國的測試是必須是一個資深研發(fā)人員才能勝任測試職位。
“測試是為發(fā)現(xiàn)錯誤而執(zhí)行程序的過程”。
一、軟件測試的原則
1. 測試用例中一個必需部分是對預(yù)期輸出或結(jié)果的定義。
? ? ? ? 一個測試用例必須包括兩個部分:
? ? ? ? ? ? ? a. 對程序的輸入數(shù)據(jù)的描述。
? ? ? ? ? ? ? b. 對程序在上述輸入數(shù)據(jù)下的正確輸出結(jié)果的精確描述。
2. 程序員應(yīng)當(dāng)避免測試自己編寫的程序.
? ? ? ? 我們大多數(shù)程序員都不能有效地測試自己編寫的程序,因為我們無法改變思維方式來盡力暴露自己程序中的錯誤。另外,我們開發(fā)者可能會下意識地避免找出錯誤來,擔(dān)心受到同事、上司、客戶或正在開發(fā)的程序或系統(tǒng)的主管的懲罰。這僅次于心理學(xué)問題所以說,更重要的是,擔(dān)心程序開發(fā)者理解錯了需求,導(dǎo)致程序出現(xiàn)錯誤。所以說,讓其他人來測試程序會更加有效,也會更容易測試成功。當(dāng)然,解決問題還是得程序開發(fā)的作者,那又回到了程序調(diào)試、解決bug的層面上。
3. 編寫軟件的組織不應(yīng)當(dāng)測試自己編寫的軟件
這個和上面一點(diǎn)很相似,但是我想說的是,效果最明顯的還是交由第三方專門的測試部門進(jìn)行測試,而該測試部門應(yīng)該是客戶層面的眼光去測試。
4. 應(yīng)當(dāng)徹底檢查每個測試的執(zhí)行結(jié)果。
解決任何的測試失敗項,避免下次測試時顯示的上一次的測試失敗項,會誤導(dǎo)開發(fā)者是新該出的bug。
5. 測試用例的編寫不僅應(yīng)當(dāng)根據(jù)有效和預(yù)期的輸入情況,而且也應(yīng)當(dāng)根據(jù)無效和未預(yù)料到的輸入情況。
6. 檢查程序是否“未做其應(yīng)該做的”僅是測試的一半,測試的另一半是檢查程序是否“做了其不應(yīng)該做的”。
這就涉及到了壓力測試及循環(huán)測試了,避免因為某個功能的實(shí)現(xiàn)導(dǎo)致上一個功能失效。或者是有規(guī)律的先運(yùn)行了某個功能,上一個功能就失效了的問題。
7. 應(yīng)避免測試用例用后即棄,除非軟件本身就是一個一次性的軟件。
測試用例應(yīng)該是被分類好,并且是一個增量的開發(fā)。這樣的好處是,將來一個新的版本relese后,就可以將之前的測試用例都過一遍,有些因為重大功能改變而導(dǎo)致的失敗,那是具體事情具體分析了。這個就是我們常說的“回歸測試”。
8. 計劃測試工作時不應(yīng)默許假定不會發(fā)現(xiàn)錯誤。
在實(shí)際測試中,不僅僅是測試正常情況下所預(yù)期的正常結(jié)果,也應(yīng)該給一些異常的測試項,測試異常的情況下,應(yīng)觸發(fā)的異常流程。當(dāng)測試異常項后,程序表面任然可以運(yùn)行的情況,也需要去排除,殊不知程序觸發(fā)了某個異常的bug,在不確定的時間才復(fù)現(xiàn)出來。
9. 軟件測試是一項極富創(chuàng)造性、極具智力挑戰(zhàn)性的工作。
測試一個大型軟件所需要的創(chuàng)造性很可能超過了開發(fā)該軟件所需要的創(chuàng)造
性。我們已經(jīng)看到,要充分地測試一個軟件以確保所有錯誤都不存在是不可能的。所以上面我說,中國與外國對測試不同的定義,我更傾向與外國的做法。
二、 代碼檢查、走查與評審
代碼檢查和代碼走查是兩種重要的人工測試方法。
代碼檢查與走查都要求人們組成一個小組來閱讀或直觀檢查特定的程序。無論采用哪種方法,參加者都需要完成一些準(zhǔn)備工作。準(zhǔn)備工作的高潮是在參加者會議上進(jìn)行的所謂“頭腦風(fēng)暴會”。“頭腦風(fēng)暴會”的目標(biāo)是找出錯誤來,但不必找出改正錯誤的方法。換句話說,是測試,而不是調(diào)試。
1. 代碼檢查(Code Inspections)
所謂代碼檢查是以組為單位閱讀代碼,它是一系列規(guī)程和錯誤檢查技術(shù)的集合。
一個代碼檢查小組通常由四人組成,其中一人發(fā)揮著協(xié)調(diào)作用。協(xié)調(diào)人應(yīng)該是個稱職的程序員,但不是該程序的編碼人員,不需要對程序的細(xì)節(jié)了解得很清楚。
協(xié)調(diào)人的職責(zé)包括以下幾點(diǎn):
- 為代碼檢查分發(fā)材料、安排進(jìn)程。
- 在代碼檢查中起主導(dǎo)作用。
- 記錄發(fā)現(xiàn)的所有錯誤。
- 確保所有錯誤隨后得到改正。
明白各自職責(zé)后,就可以對代碼流程進(jìn)行檢查,任何有疑問的都應(yīng)該被記錄下來,并列好解決方法。以會議的形式開展,既然是開會,時間大概是30分鐘到1個小時,視具體項目而定,但是開會是一個耗費(fèi)腦力的活動,不易過長,不然越到后面效率越低。
2. 代碼走查(Walkthroughs)
與代碼檢查相同,代碼走查參與者所持的態(tài)度非常關(guān)鍵。提出的建議應(yīng)針對程序本身,而不應(yīng)針對程序員。換句話說,軟件中存在的錯誤不應(yīng)被視為編寫程序的人員自身的弱點(diǎn)。相反,這些錯誤應(yīng)被看作是伴隨著軟件開發(fā)的艱難性所固有的。很多時候有些直屬領(lǐng)導(dǎo)會直接就事論人,這樣就會讓軟件開發(fā)作者受到打擊,并且樹立不好的形象,最終導(dǎo)致整個開發(fā)團(tuán)隊氛圍的改變。不要在事后說控制不住或者性格這樣請見諒的話,一旦不好的風(fēng)在團(tuán)隊中刮起來,會導(dǎo)致團(tuán)隊中的成員或多或少心里有個帶爆發(fā)的小宇宙,就不知道什么時候會爆發(fā)而已。所以說,態(tài)度很重要。
3. 桌面檢查(Desk Checking)
人工查找錯誤的第二種過程是古老的桌面檢查方法。桌面檢查可視為由單人進(jìn)行的代碼檢查或代碼走查:由一個人閱讀程序,對照錯誤列表檢查程序,對程序推演測試數(shù)據(jù)。
對于大多數(shù)人而言,桌面檢查的效率是相當(dāng)?shù)偷摹F渲械囊粋€原因是,它是一個完全沒有約束的過程。另一個重要的原因是它違反了上文提出的測試原則,即人們一般不能有效地測試自己編寫的程序。因此桌面檢查最好由其他人而非該程序的編寫人員來完成(例如,兩個程序員可以相互交換各自的程序,而不是桌面檢查自己的程序)。但是即使這樣,其效果仍然遜色于代碼走查或代碼檢查。原因在于代碼檢查和代碼走查小組中存在著互相促進(jìn)的效應(yīng)。小組會議培養(yǎng)了良性競爭的氣氛,人們喜歡通過發(fā)現(xiàn)問題來展示自己的能力。而在桌面檢查中,由于沒有其他人可供展示,也就缺乏這個顯而易見的良好效應(yīng)。簡而言之,桌面檢查勝過沒有檢查,但其效果遠(yuǎn)遠(yuǎn)遜色于代碼檢查和代碼走查。
4. 同行評分(Peer Ratings)
這種人工評審方法與程序測試并無關(guān)系(其目標(biāo)不是為了發(fā)現(xiàn)錯誤),卻仍在這里談到,這是因為它與代碼閱讀的思想有關(guān)。同行評分是一種依據(jù)程序整體質(zhì)量,可維護(hù)性、可擴(kuò)展性、易用性和清晰性對匿名程序進(jìn)行評價的技術(shù)。該項技術(shù)的目的是為程序員提供自我評價的手段。
三、 模塊(單元)測試
模塊測試(或單元測試)是對程序中的單個子程序、子程序或過程進(jìn)行測試的過程,也就是說,一開始并不是對整個程序進(jìn)行測試,而是首先將注意力集中在對構(gòu)成程序的較小模塊的測試上面。這樣做的動機(jī)有三個。首先,由于模塊測試的注意力一開始集中在程序的較小單元上,因此它是一種管理組合的測試元素的手段。其次,模塊測試減輕了調(diào)試(準(zhǔn)確定位并糾正某個已知錯誤的過程)的難度,這是因為一旦某個錯誤被發(fā)現(xiàn)出來,我們就知道它在哪個具體的模塊中。第三,模塊測試通過為我們提供同時測試多個模塊的可能,將并行工程引入軟件測試中。
這是我所親身經(jīng)歷的。當(dāng)時我在開發(fā)一個平臺代碼,python。可以說是一個中性的系統(tǒng),但是模塊分工明確,開發(fā)人員分工也明確。所以當(dāng)我們編寫好自己所負(fù)責(zé)的模塊后,自己編寫單元測試代碼,通過打樁,讓每一行、每一個代碼分支都被覆蓋。而當(dāng)時我們使用pytest、mock模塊,結(jié)合Jenkins平臺,就可以搭建出一個可視化的測試平臺,查看代碼覆蓋,沒有覆蓋的代碼會標(biāo)記不同的顏色,很方便查閱。通過對每一行、每一個分支的覆蓋測試,這樣代碼質(zhì)量就提高了。
當(dāng)然每種語言都有他相應(yīng)的單元測試模塊,但是思想是一致的,即不需要運(yùn)行系統(tǒng),就可以將模塊代碼中的每一個邏輯都覆蓋到。
四、 調(diào)試(DEBUGGING)
下面列舉了一些常用的調(diào)試手段。
1. 暴力法調(diào)試(Debugging by Brute Force)
調(diào)試程序的最為普遍的模式是所謂的“暴力”方法。這種方法之所以流行,是因為它不需要過多思考,是耗費(fèi)腦力最少的方法,但同時也效率低下,通常來講不是很成功。
暴力調(diào)試方法可至少被劃分為三種類型:
a. 利用內(nèi)存信息輸出來調(diào)試。
b. 根據(jù)一般的“在程序中插入打印語句”建議來調(diào)試。
c. 使用自動化的調(diào)試工具進(jìn)行調(diào)試。
?
2. 歸納法調(diào)試(Debugging by Induction)
認(rèn)真的思考能夠發(fā)現(xiàn)大部分錯誤,甚至不需要調(diào)試人員使用調(diào)試工具。歸納是一種特殊的思考過程,可以從細(xì)節(jié)轉(zhuǎn)到全局,也就是從線索(即錯誤的癥狀,可能是一個或多個測試用例的結(jié)果)出發(fā),尋找線索之間的聯(lián)系。參見下圖:
3. 演繹法調(diào)試(Debugging by Deduction)
演繹的過程是從一些普遍的理論或前提出發(fā),使用排除和精煉的過程,達(dá)到一個結(jié)論(錯誤的位置),參見下圖:
4. 回溯法調(diào)試(Debugging by Backtracking)
在小型程序中定位錯誤的一種有效方法是沿著程序的邏輯結(jié)構(gòu)回溯不正確的結(jié)果,直到找出程序邏輯出錯的位置。換句話說,從程序產(chǎn)生不正確結(jié)果(如打印了不正確的數(shù)據(jù))的地方開始,從該處觀察到的結(jié)果推斷出程序變量應(yīng)該是些什么值。在頭腦中,從這個位置開始逆向執(zhí)行程序,重復(fù)使用“如果程序在此處的狀態(tài)是這樣的,那么程序在上面位置的狀態(tài)就必然是那樣的”過程,就能很快定位出錯誤。使用這個過程,可以確定程序中從狀態(tài)符合預(yù)期值的位置點(diǎn),到第一個狀態(tài)不符合預(yù)期值的位置點(diǎn)之間的范圍。
5. 測試法調(diào)試(Debugging by Testing)
最后一個“思維型”的調(diào)試方法是使用測試用例。這可能聽起來有些奇怪,因為從本章一開始就將調(diào)試和測試區(qū)分了開來。然而,考慮下面兩種類型的測試用例。供測試的測試用例,其目的是暴露出以前尚未發(fā)現(xiàn)的錯誤.供調(diào)試的測試用例,其目的是提供有用的信息,供定位某個被懷疑的錯誤之用。兩者之間的區(qū)別是,供測試的測試用例會“胖”一些,因為我們盡量使用較少數(shù)量的測試用例來涵蓋較多的條件,而供調(diào)試的測試用例則“瘦”一些,因為每個測試用例僅需要覆蓋一個或幾個條件。換句話說,當(dāng)發(fā)現(xiàn)了某個被懷疑的錯誤的癥狀之后,我們需要編寫與原先有所變化的測試用例,盡量確定錯誤的位置。實(shí)際上,這種方法不是一個完全獨(dú)立的方法;它常常結(jié)合歸納法一起使用,以獲得進(jìn)行假設(shè)和/或證明假設(shè)所需的信息。它也可以和演繹法一起使用,以排除有嫌疑的原因,提煉剩下的假設(shè),并/或證明假設(shè)。
?
五、 調(diào)試的原則
1. 定位錯誤的原則
- 動腦筋
- 如果遇到了僵局,就留到稍后解決
- 如果遇到了困境,就把問題描述給其他人聽
- 僅將測試工具作為第二種手段
- 避免使用試驗法——僅將其作為最后的手段
2. 修改錯誤的技術(shù)
- 存在一個缺陷的地方,很有可能還存在其他缺陷
- 應(yīng)糾正錯誤本身,而不僅是其癥狀
- 正確糾正錯誤的可能性并非 100%
- 正確修改錯誤的可能性隨著程序規(guī)模的增加而降低
- 應(yīng)意識改正錯誤會引入新錯誤的可能性
- 修改錯誤的過程也是臨時回到設(shè)計階段的過程
- 應(yīng)修改源代碼,而不是目標(biāo)代碼
3. 錯誤分析
- 錯誤出現(xiàn)在什么地方?這個問題是最難回答的問題之一,它需要通過對程序文檔和項目歷史進(jìn)行回溯研究,但同時它也是最有價值的問題。它要求我們指出該錯誤的源頭和發(fā)生時間。舉例來說,錯誤的源頭可能是規(guī)格說明中的一個模棱兩可的語句,對先前錯誤的一次修改,或?qū)ψ罱K用戶需求的一個錯誤理解,
- 誰制造了這個錯誤?如果發(fā)現(xiàn)有 60 %的設(shè)計錯誤都是由 10 名軟件分析師中的某個人犯下的,或某程序員犯的錯是其他程序員的 3 倍,難道這不是相當(dāng)有用么?(不是為了處罰某人,而是為了進(jìn)行培訓(xùn)。)
- 哪些做得不正確?僅僅判斷錯誤的發(fā)生時間和出現(xiàn)人員還不夠,其中丟失的環(huán)節(jié)是準(zhǔn)確地判斷出錯誤發(fā)生的原因。錯誤是由于某人寫得不清楚?是由干某人缺乏對該編程語言的培訓(xùn)?是打字錯誤?假設(shè)做得不對?還是因為沒有考慮有效輸入?
- 如何避免該錯誤的出現(xiàn)?在下一個項目中可以進(jìn)行哪些調(diào)整以避免該問題的出現(xiàn)?此向題的答案就是我們所尋找的最為寶貴的反饋信息或知識。
- 為什么錯誤沒有早些發(fā)現(xiàn)?如果錯誤是在測試引入段發(fā)現(xiàn)的,我們就應(yīng)該研究為什么在更早些的測試階段、代碼審查和設(shè)計評審中沒有發(fā)現(xiàn)該錯誤。
- 該如何更早地發(fā)現(xiàn)錯誤?這個問題的答案是另一個寶貴的反饋信息。該如何改進(jìn)評審和測試過程以便在將來的項目中更早地發(fā)現(xiàn)同類型的錯誤?假設(shè)分析的問題不是由最終用戶發(fā)現(xiàn)的(也就是說,是由測試用例發(fā)現(xiàn)的),我們就應(yīng)意識發(fā)生了一些有價值的事情:我們編寫了一個成功的測試用例。這個測試用例為什么會成功?我們是否能從中學(xué)習(xí)些什么,無論是針對該程序還是將來的程序,設(shè)計出更多的成功用例?
再一次申明,分析的過程是很艱難的,但是找到的答案為改進(jìn)后續(xù)的編程實(shí)踐提供極其寶貴的價值。值得警惕的是,絕大多數(shù)的程序員和編程機(jī)構(gòu)都尚未使用這種方法。
總結(jié)
以上是生活随笔為你收集整理的【读书笔记】-《软件测试的艺术》的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 查看当前提供了哪些引擎
- 下一篇: 家庭组计算机无法,【求助】Windows