iT邦幫忙

DAY 25
7

如何提升系統設計品質 - 技術與工具以.NET為例系列 第 25

[如何提升系統品質-Day25]測試 - 自動化測試經驗分享

今年微軟TechDays有幸獲得主辦單位邀請,擔任一場BoF的講師(其實應該算主持人才對),題目是『自動化測試實戰經驗分享』。因為是討論型態,所以主題就放在導入與實際運行的一些經驗,而不是著重在工具、工法和理論。重要的是,讓大家可以知道,世界沒有想像的這麼美好,但我們可以從自己做起。

這篇文章,就針對當天課程的一些議題,提出我的一些想法。(放在每個表情符號後面)

[如何提升系統品質]系列文章連結

本文的Reference:(內容裡面放不下去了)
1.軟體構築美學, Brownfield Application Development in .NET
2.軟體測試之道, How We Test Software at Microsoft
3.軟體測試實戰 Visual Studio & Team Foundation Server
4.The Art of Unit Testing With Esamples in .NET
5.代碼整潔之道, Clean Code - A Handbook of Agile Software Craftsmanship
為何需要測試
因為需要信心!測試可以帶來品質的保證,就像在工地高空工作的工人一樣,他們絕不會預期自己會從高空墜落,就如同撰寫完程式,不會預期它將出錯。但是高空作業還是需要相對的安全措施,才不會活在恐懼中。沒有測試保護的系統,任何修改系統的動作,都有可能導致其他的Defact發生。這會嚴重的影響到整個團隊,包括使用者、開發人員、分析人員、管理人員的信心,一個不良系統完成後,大家不敢去修改它,而用許多繞圈的方式,來達到目的。結果就是大樓越蓋越歪,因為沒人敢在去動任何一根鋼筋,任何一塊磁磚。

rock:測試可以讓我們,不再只是靠直覺來判斷,系統是否如同預期的運作,可以不用再活在改變的恐懼中。

無間地獄
無間地獄,這就是絕大部分沒有完整測試的現狀。通常有哪些徵狀?
1.系統整合時出現錯誤,是誰的程式導致的錯誤?出錯點不一定是錯誤的根源。
=>該怎麼證明自己的程式沒有問題?
=>該怎麼迅速的找出,究竟是哪一個模組出現出乎預料的結果?

讚:測試可以保護自己,可以迅速找出問題,降低尋找問題的成本。

2.改了這支程式,其他的程式會不會被影響?
=>其他程式到底是應該跟著修改,還是不應該被影響?
=>自己的程式好了就好,管其他人去死?(別忘了『自己』也包含在『其他人』的子集合裡面)

抱抱:讓迴歸測試結果來回答

3.交付的程式,到底測過哪些東西?
=>為什麼測試報告總是一份Word, Excel文件,那一些checklist的項目,勾選真的有意義嗎?勾選完就可以保證不會出現錯誤嗎?真正的測試報告,應該是即時的,且避免人操作上的主觀跟誤差。

飛:測試報告應該由程式碼或工具來產生,降低人為誤判,提升速度,即時且數據化的產出系統的健康報告。

4.他的功能還沒寫好,我沒法子測我的程式。
=>程式耦合性太高,在現在的分工模式下,可能會導致開發人員互相等待的情況發生。導致平行開發的速度降低,測試的時間往後延遲,開發人員彼此又用直覺在猜測功能應該如何運作,應該可以正常運作。所以通常在SIT的時候,程式整合完會哀鴻遍野的原因就在這。

敲碗:可測試性為系統品質的重要指標之一,具備可測試性,可確保程式的耦合性低,可透過Mock/Stub模擬外界回應,讓每一個功能單元都更加獨立。

5.一盒咖哩塊的故事。
=>為什麼買其他東西都沒有問題,只有買咖哩塊就會出錯?程式看起來都沒問題,但因為要使用到外部的service,無法在本機端測試。結果:為了測試正式環境上到底出現了什麼問題,隔天就收到了訂購的咖哩塊。

汗:當程式依賴外部服務,才能正常運作,才能測試哪裡出錯,才能還原現場時,要付出的代價可能超乎想像。為了怕這代價,可能只能瞎子摸象,只是變相的成本轉嫁。

6.無間地獄的由來:
佛曰:『受身無間者永遠不死,去壽長乃無間地獄中之大劫。』
簡單的說,就是『品質低落的系統活越久,維護的人越痛苦。
斬不斷,理還亂,身陷無窮痛苦迴圈。

為什麼需要自動測試
1.確保bug不會重覆出現。
疑惑:Bug的修復成本很高(高在哪?並不是高在功能修正,而是高在測試範圍跟不可預期的連帶影響風險),Bug應該只要修一次。

2.確保新程式達到可接受的品質水準。
飛:每一段新的程式,就像建立起自己的防火巷,即使燒起來,也可以確保不會延燒至其他模組。

3.建立與保持開發團隊和使用者的信心。
驚:看不到,所以心生恐懼。(跟鬼一樣…)當可以即時地得到數據化的測試報告時,就可以多一分掌握系統的把握。

4.加速回饋循環。

當系統越晚進行修正,所需付出的成本就越大。什麼時候才會知道哪些東西需要修正,絕大部分都在測試完才會知道。

哈哈:所以要降低系統的改變成本,簡單的說,就是把測試的時間點往前推,或是對每個階段都進行測試,來降低未來指數上升的成本負荷。

4.『程式撰寫』與『測試』哪一個時間花的多?
直覺上,是程式撰寫花的時間多。內行人會說,測試花的時間多。因為每一行的程式一撰寫完,就進入維護階段了。每一個功能完成就開始進行測試了。(不論是什麼形式的測試)大部分管理者的時程預估,卻都是測試時間<開發時間。為什麼會發生這樣的狀況?最常見的原因就是,『先求有,再求好』。這句話很實用,也很無奈。但這句話在軟體開發是有問題的,至少應該修正成『先求對,才會有,再求好』。交付一個有問題的程式,就會變成上面那張曲線圖,先求有的結果,是帶來無止盡、無形的維護成本。

自動化測試的確需要投入成本,增加的是建置與開發的成本,但對整個系統的成本來說,如果系統需要維護(每個系統都需要維護),是降低的。因為測試跟維護的成本佔了很大的比例。

嗚:自動化測試,就是透過infrastructure,將測試的時間大幅縮短,並提升可信度。以有形的建置與開發成本,降低漫無目的的測試及無形的維護成本。

5.自動化測試的六個元素:SEARCH
(1)Setup:環境建置。包括版本控管、持續整合(CI)建設、初始化測試環境與測試資料的準備。

(2)Execution:執行。驗證功能、錯誤處理等等…

(3)Analysis:分析是決定測試通過或失敗的程序。也就是要定義什麼樣的情況是成功,什麼樣的情況是失敗。通常包含著domain know-how。

(4)Reporting:報告。指的是分析的呈現和解釋。可能會透過數據報表、圖示、燈號,以不同的方式呈現,例如Portal中的DashBoard、Mail通知等等…

(5)Cleanup:將所有執行完的環境與資料,還原成原本的狀態,以便進行下一輪測試。

(6)Help:其他的輔助,例如如何增加測試案例,如何更有效的整合和回饋到系統的開發與測試。(例如使用FitNesse來讓使用者提供測試案例)

6.是不是所有的測試都要自動化
不一定,這是一種取捨。一味的全面導入自動化測試,通常只會失敗收場。因為初期投入成本過高,穩定性又不足,開發團隊很容易碰到挫折後,失去信心。管理者更會因為成本與效益無法達到目標,而對『自動化測試』失去信心。

衝刺:把握80/20法則,從兩個面向當切入點:
1.最容易開始自動化測試,不會花什麼成本的方式,開始做自動化測試。例如:效能測試、壓力測試、負載測試、安全測試、單元測試。
2.從以往或預估會花最多測試與品質成本的地方,開始導入自動化測試。雖然過程痛苦,但成本回收比會讓前面的辛苦獲得甜美的果實。例如:單元測試、整合測試,準備測試環境、測試資料,初始化與還原的機制。

一分鐘到了,你的夢醒了嗎?
歡迎回到現實世界,現實世界畢竟不是烏托邦。即使知道了自動測試的工具、方法,也擁有著開始改變的衝動與熱忱,但還是會碰到讓人沮喪氣餒的情況。

有心殺賊,無力回天
1.開發時程沒有將測試時程估進去。
=>程式寫得好的話,為什麼測試需要花這麼多時間?

2.管理者短視近利。
=>就是『先求有,再求好』那一套,縮短測試的時間,將問題歸咎於開發的品質不好。

3.團隊抗拒改變。
=>按照以前的方式,程式也可以正常運作,為什麼又要搞這麼多有的沒的,又麻煩又花時間又收不到效果。
=>不要企圖改變前人的方式與修改版本庫上的東西,他們會存在,有一定的理由。

4.沒有測試與建置環境。
=>沒有機器,沒有預算,沒有多餘的人管理機器。

5.無法提供仿真測試資料。
=>客戶無法提供資料。沒有時間做資料。上線後就可以用真實資料來測。

6.YAGIN,KISS。
=>為了還沒發生的問題,花這些時間做這些事,沒有意義。

嘆氣:出來跑,總是要還的。要說服上層拿到時間、人力、硬體資源來進行自動化測試,還要改變其他人的習慣或團隊文化,是幾近於不可能的事情。

木已成舟
1.找不到時間點做測試。
=>開發時間都不夠了,還要做什麼測試。

2.棕地程式不具備可測試性。
=>沒有測試保護就不能重構。沒有重構就無法讓程式具備可測試性。

爆氣:任何Bug修復、功能異動,都需要測試來確定自己這次的動作達到需求,這就是最好的時機。
面對棕地程式,建議先建立成本低的黑箱整合測試,挑選幾個在code coverage可涵蓋到較多範圍的test case著手。有了外層簡單快速的黑箱整合測試保護,再著手進行棕地程式的重構。在這個同時,將單元測試建立起來,在這一小塊模組中,清除棕地成為綠地。那怕要改的,只有一行code,只要是新的功能,只要是有問題的Defact,為它特地建立一個單元測試,都是值得的。因為Bug的修復成本很高!

半途而廢,功虧一簣
1.維護的人不看測試結果,不寫測試程式。
=>我不懂,不想懂,何必懂。

2.破窗理論。
=>當一個洞不去理他的時候,很快的就會越破越多洞。

維護人員:

曾經有一份完整的測試專案擺在我的面前,但我不懂得珍惜。等到系統壞到不可收拾的時候,才後悔莫及。自動測試最痛苦的事莫過於此。如果上天給我個機會可以重來一次的話,我會對這個測試專案說:我愛她。如果非要在這份愛上面加上一個期限,我希望是直到永遠。

無言:Production code與測試專案,應該是生命共同體,是一體的兩面。每一次的修改,都應有對應的測試案例來證明這一次的修改是符合預期運作的。前面的團隊革命無數次,耗費了多少的心血、努力、時間,才擁有了一份可運作的測試專案,為的就是讓維護人員可以輕鬆的handover,維護人員將測試專案置之不理,就像三國劉備辛苦了大半輩子,最後被一個無能的劉禪把祖業敗掉一樣可悲。

變法通常都會失敗
是的,這些痛苦,我們都經歷過,這也是必經的過程。變法通常都會失敗,因為沒人喜歡大掃除,人性抗拒改變。請不用灰心、沮喪,還是可以先逐步的建立起自己的烏托邦,用事情結果來改變人,而非用人來改變事情。這通常是導入自動測試的第一步。

文化=多數人的價值觀
改變文化是困難的,因為『文化=多數人的價值觀』,『少數服從多數』是一直存在的隱規則。要改變文化的不二法門,就是讓自己成為多數人。一個很好用的方式,就是以三為一個單位。最小單位就是三人一組,想辦法讓自己成為三人中的二人組,被孤立的那一人,就會跟上,或被淘汰。

任何會增加開發困擾的要求,都很容易造成導入失敗。重點是,如何透過自動測試,來增加他們的生產力,降低他們既存的困擾,最好可以讓他們更輕鬆地開發,有更多的時間可以休息。

可以從哪邊開始
1.版本控管 (TFS, SVN, Git, VSS…)
2.去除程式的相依性(IoC, Mock)
3.建立第一個測試專案與第一個單元測試
4.建立一個可自動執行的測試腳本
5.爭取主管同意與支持
6.找一個可控制風險的目標系統,有意願撰寫自動測試的developer,逐步改善品質,建立文化

環境建置的重點:
1.版本控管
2.持續整合基礎建設
3.獨立且仿真的測試環境

自動化測試常見的錯誤
1.hard-code的路徑
=>測試專案無法獨立運作。

2.複雜度太高
=>production code寫太爛,導致單元測試撰寫時間過長,異動頻率變高,異動範圍過大,維護測試專案成本提升,信心喪失,放棄單元測試

3.難以找出問題
=>測出有問題,卻無法迅速知道問題的原因。

4.誤報
=>誤報分兩種,第一種是對的程式,測試結果報錯。第二種是錯的程式,測試結果報對。後者的嚴重程度比前者大很多,一定要避免。

5.龜速測試
單元測試專案與整合測試專案沒有分開。單元測試應該在任何環境底下(包括沒有資料庫、沒有網路等)可以獨立且迅速運行。整合測試因為會需要外界服務的存取,還外加需要初始化與還原環境跟資料,所以相當耗時。

結論
建立第一個測試專案,第一個單元測試,就對了。跨出第一步之後,才能達到目標。

自動化測試,才是『預防勝於治療』的王道。


上一篇
[如何提升系統品質-Day24]測試 - Code Coverage
下一篇
[如何提升系統品質-Day26]測試 - 問題單該提供的資訊
系列文
如何提升系統設計品質 - 技術與工具以.NET為例30
0
pajace2001
iT邦研究生 1 級 ‧ 2013-04-09 15:37:07

筆記真是相遇很晚哪~哭

0
HoiDam
iT邦新手 5 級 ‧ 2020-09-25 16:59:39

那請問一下前輩有甚麼好的軟件推薦嗎?

我要留言

立即登入留言