這一篇文章是我投稿到ZDNet的《SQA怎麼做的實戰教學(上)、(下)》的原稿,該文標題經編輯修正。
在這一篇文章中,我們將進一步從上篇文章《Tester vs. SQA - 4/ 關係與差異》中的差異處,繼續說明SQA在軟體開發過程中的工作。
Tester的焦點
集中在軟體的每個版本中:
- 加入多少新功能?
- 有那些功能變更?
- 上個版本的Bug是否都已經被解了?
- Developer又自行測出那些Bug?
- 還有那些Bug沒有解?
所以,Tester會去設計新的Test Case以Cover這些新的/修改後的程式。換句話說,測試的函蓋率(Coverage Rate)越高,他們對於軟體品質的信心水準越高。
SQA的焦點
則與Tester不同。他們關心的是在每個版本中:
- 加入的新功能/變更是否都照開發程序走完流程?
- 上個版本發現的Bug是否都已經釐清?

SQA認為藉由這些手法能有效地改善(開發)系統,而藉由持續不斷地重覆這些活動,將可提供他們對於軟體品質的信心。
實務上
當我在擔任SQA時,看到Bug時並不會每個Bug都去追,而是信任Developer由他們自行對Bug提出解決方案,我只去統計追蹤這些Bug的後續發展,直到我發現Bug 開始已經形成某種模式(Pattern)時,我才會介入。
因為,根據80/20分則,80%數量的Bug會同時指向某些重覆、特定20%的目標,例如:
- 某個Developer
- 某個系統的某個功能
- 某支程式
- 某個被使用的元件
例如當發生「使用A Library時常會發生錯誤」的模式出現時,這時我會繼續追兩件事:
- 錯誤的原因(Root Cause);
- 脫逃點(Escape Point)
錯誤的原因(Root Cause)
筆者會一直重複「結果→原因」問為什麼的過程,以找到一次因、二次因…、直到找到無法再繼續向下探索的n次原因,這個原因通常被稱為「根因」(Root Cause)。這個過程類似TOYOTA豐田汽車實施的改善流程方法「五個WHY」,一旦發現問題便接連問五次「為什麼」,藉此看清問題的根因。
假設問題是「使用A Library時常會發生錯誤」時,原因有可能是:
- 濫用(abuse),如:原本應該使用Y元件,但使用了Z元件;
- 元件本身就有問題,即使依照A Library 的User Guide操作,仍然會發生問題;
- 誤用(misuse),例如:原本應該用function big(a, b, c) ,卻使用成function big(a, b)
假設原因是誤用(misuse)時,筆者會再進一步去釐清Developer會誤用的原因:
- 是因為Developer不知道該如何正確使用元件
- 還是Y元件和Z元件設計的功能太相近了,即使說明了,也很容易讓人搞混以致於誤用?
- 是Developer沒有看User Guide就開始Coding?
- 又或是Developer根本不知道有User Guide?
如果原因是「Developer沒有看User Guide就開始Coding」,那表示是Developer明知道有User Guide,卻沒有看。這時候就要再去問:
- 為什麼Developer沒看User Guide,但Team Leader不知道?
- 是給Developer的時間不夠,連看的時間也沒有?
- 還是已經給Developer足夠的時間看User Guide了,但Developer還是沒有看完?
找到Root Cause後接下來就是要找到「脫逃點」。
脫逃點(Escape Point)
通常是指既有的系統內,因為某項檢核、確認機制失效或未發生作用,以致於無法透過既有系統篩檢出隱藏的缺失,才導致異常狀況在系統外才被發現。
假設系統是個捕魚的魚網,如果發現網外有一隻比魚網孔目還要大的漏網之魚,這時候你得先確定是捕進來的魚漏掉了?還是根本捕不到這條魚?
假設是前者,你還得繼續確認是魚網的某個地方破了?還是這個魚網的孔目有方向性,魚從某個方向進來會溜掉?或是有其他的原因?
所以,當客戶發現某個Bug時,就要再繼續找為什麼Bug無法被既有的Test Plan/Test Case測出的原因:
- 因為Test Case的Coverage不足?所以根本沒有發生Bug條件的Test Case?
- 或是Test Case的條件不足,有其他條件但就是沒有發生Bug的條件?
- 或是根本沒有執行該項Test Case?
- 或是有以上之外的原因?
無論如何,都一定要找出缺失會從既有系統溜出去的原因,才有辦法改善現有的網,以避免相同的問題再度發生。
改善方案
一般而言,筆者會採用兩種方法:
- 矯正措施(CA, Corrective Action)
- 預防措施(PA, Preventive Action)
CA通常是矯正既存異常狀況,或是排除造成異常狀況原因的對策。例如前面的「使用A Library時常會發生錯誤」問題,CA就是:透過正確的方式修正Code;PA則包含排除Root Cause、Escape Point、或類似狀況的對策。
Root Cause和Escape Point前面已經說明了,只要分析出的Root Cause和Escape Point夠正確,一般而言要提出排除這類狀況的手法並不困難;倒是「類似狀況」則需要再多說明。
所謂的「類似狀況」是指會發生此一缺失,但卻可能不是目前Root Cause的其他原因。
例如前面的「使用A Library時常會發生錯誤」問題的Root Cause 假設是:「給Developer了解Guide的時間不夠」時,就可以把「類似狀況」判斷為「Developer不知道該如何正確使用元件」,以找出更多的「類似狀況」,例如:
- 使用手冊說明/案例不夠清楚,以致於不易理解;
- 缺少精要的Training Material,以致於無法縮短上手的時間;
- Bug Pattern未加入此一案例,以致於無法從過去的錯誤中很快地學習正確的方式。
用這個方式,很快的就能網羅一堆可能造成類似狀況的對策。
Fan Out
則是個特殊的單字,其實指的就是從一個點扇形展開的意思。放在SQA的領域,可以當成改善案例展開、或分享。
「展開」的應用情況,可以在了解PA、CA後,一併作的處理。以上面的例子「Developer A因為不知道該如何正確使用元件,所以使用Y元件時,總是會誤用」。如果筆者來作Fan Out時,會請Developer A去Search過去他曾修改過、使用Y元件的程式,以確認是否重覆誤用,以提前將這個問題解決。
「分享」的應用情況,以前面的「Developer A誤用Y元件」的例子來說,筆者會請Developer A作出Y元件的Bug Pattern,並請他對Development Team報告,讓其他的Developer也能很快地了解這個問題的始末,並很快地偵檢出各自的Code是否也有類似的問題。
確認
當SQA作完上述的活動後,為了確認問題的解決手法真的具有解決問題的能力,一般而言會需要一段時間觀察缺陷是否還會復發。因為客戶最終是否滿意,取決於這些解決手法是否有效。
確認所需的時間,通常會視問題出現的難易度來決定。一個越容易重製(Reproduce)的問題,就越容易確認問題是否被解決,所需觀察的時間也越短。
另外,能提供確認的對象越多,其結果也就越能作為確認的依據。例如:Beta版散佈的對象越多,可以確認改善方案的有效性保證越可靠。
結語
上述的步驟,在某些公司的名稱雖略為不同,在執行順序上也略有不同,但流程背後執行PDCA的精神是相同的。
另外,這個步驟其實還是延續《Tester vs. SQA - 4/ 關係與差異》一文中打靶的觀念:「射『對」』標比射『準』目標來得更重要。」的精神:執行的結果,取決於一開始找到的根因是否準確。
找到越準確的根因,經過上述步驟的結果也就越有效。射不準正確目標還可以在下一發子彈修正;一旦瞄準了錯誤目標,就不會因為你下一發射準誤目標就變得更好。
此外,上面的手法其實非常簡單,一般人有心只要稍加訓練後就能很快學會,但往往很不容易作到。
除了因為在開始之前,就必須先建立一個明確、有效的流程(這個流程的形式不是重點,導入CMMI、ISO都可以辦到)之外;也因為建立流程者眾,但想認真、徹底執行流程者寡。因為從筆者過去觀察到某些未導入CMMI、ISO的公司也可以有相同效果來看,真正的關鍵取決於管理者的決心與遠見。
筆者認為這才是業界中難得看到認真執行SQA手法的原因。
認真執行的人少了,真正的SQA自然也就少了。
沒有留言:
張貼留言