自動化測試中的那些誤解和偏見

  • 2019 年 10 月 7 日
  • 筆記

自動化測試是手工測試的唯一出路么?當我想到這個問題時候,我也覺得好笑。醫生是護士唯一的出路么?將軍是士兵的唯一出路么?

因為最近混了一些論壇以及群看別人的討論。發現好多人認為自動化測試是測試人員的唯一出路。

工人是農民的唯一出路么?也許是,農民工。為什麼想到這個問題,因為發現很多人就是這麼認為的,而且認為是唯一出路。

對測試和品質認知有誤解的,遠不止這個。

有一些公司,比如一些初創公司,對測試人員的考核,非要靠一個硬性的指標,比如:Bug 率,Bug 遺漏率,測試開發比,自動化測試率; 我不知道這些比例是如何計算出來的。

Bug 率:我搜索一下還真有這玩意。 流行的公式主要以下兩個: 觀點一、bug率=bug數/程式碼行數 觀點二、bug率=bug數/功能點數 我不知道哪個公司蛋疼得統計這玩意。出現bug的因素有很多,比如歷史遺留問題,架構設計局限,需求的理解,項目進度,項目資源等。 從考核標準上來說,Bug率數值越小就說明越好,基於這個結果,會引導團隊成員做出一些對長遠和整體效率無益的行為,例如:

增大基數,增加無意義程式碼

把定長循環分開寫,寫成順序方法

把可配置資訊寫死到程式碼中

大量的複製、粘貼程式碼

重新發明各種輪子

Bug 遺漏率: 品質從來不是測出來的。 系統品質是要靠上游工程做出來的,而且上游的工作品質會更為重要,上游的問題的影響範圍將更廣,對效率和價值的影響更大,應該是我們重點關注的地方。僅僅依賴下游工程(種種測試)來把品質關,是十分低效,而且代價是非常昂貴的。

開發測試比:

這個比例並不太能說明測試人員的效率,或者公司對品質的重視程度。 基本上每家公司都是不一樣的。這個原因有很多,公司傳統,領導風格,人員素質,工作內容,等等……如果離開了當前公司的這個Context去談開發測試比,並沒有太多的意義。就譬如說兩家公司的開發測試比都是3:1,但是其中一家公司的可能很糟蹋,另一家很高效。談這個開發測試比例,最好是在相同的類型的公司(創業型VS大公司),相同的行業(互聯網VS傳統),人員素質在同一個水平,等等。在這些前提條件下,如果發現自己的所在的組織的效率不如其他公司,可以參考同行有什麼好的實踐,取其精華去其糟粕。開發測試比例只是浮雲,整個組織的效率才是關鍵。

自動化測試率: 對於快速迭代的互聯網公司來說,這個還真不好弄,除非你不迭代,測穩定的版本。像以前的傳統的大型項目,發布周期特別長,可以弄弄。或者你有足夠多的資源,足夠人員來弄這個,而且這個是滯後的,可能你某個功能自動化起來了,某次迭代又改得面目全非,投入產出不成比例。而很多人誤解就是,自動化測試比例越多,就證明效率越高,越能節省人工。有公司大言不慚的說,我們的自動化測試率是100%。對於簡單的測試,可能錄製就能達到,真正複雜一點的,你敢全面用自動化來測試么?

OK, 既然把自動化測試抬得如此高,我們來看看自動化測試是何方神聖。

自動化測試的優點:

1、對程式的回歸測試更方便。這可能是自動化測試最主要的任務,特別是在程式修改比較頻繁時,效果是非常明顯的。由於回歸測試的動作和用例是完全設計好的,測試期望的結果也是完全可以預料的,將回歸測試自動運行,可以極大提高測試效率,縮短回歸測試時間。

2、可以運行更多更繁瑣的測試。自動化的一個明顯的好處是可以在較少的時間內運行更多的測試。

3、可以執行一些手工測試困難或不可能進行的測試。比如,對於大量用戶的測試,不可能同時讓足夠多的測試人員同時進行測試,但是卻可以通過自動化測試模擬同時有許多用戶,從而達到測試的目的。

4、更好地利用資源。將繁瑣的任務自動化,可以提高準確性和測試人員的積極性,將測試技術人員解脫出來投入更多精力設計更好的測試用例(把節省的人力投入到更有意義的用例設計上)   將可自動測試的測試自動化後,可以讓測試人員專註於手工測試部分,提高手工測試的效率。

5、測試具有一致性和可重複性。由於測試是自動執行的,每次測試的結果和執行的內容的一致性是可以得到保障的,從而達到測試的可重複的效果。(腳本的復用性)

6、測試的復用性。由於自動測試通常採用腳本技術,這樣就有可能只需要做少量的甚至不做修改,實現在不同的測試過程中使用相同的用例。

7、增加軟體信任度。由於測試是自動執行的,所以不存在執行過程中的疏忽和錯誤,完全取決於測試的設計品質。一旦軟體通過了強有力的自動測試後,軟體的信任度自然會增加。

自動化測試的缺點:

1、不能取代手工測試

2、手工測試比自動測試發現的缺陷更多,自動化測試不容易發現新的BUG

3、對測試品質的依賴性極大(理解:自動化測試腳本的正常運轉前,需要先經過功能測試的通過)

4、測試自動化不能提高有效性(理解:主要從維護腳本的花費資源上來看,並不能節省資源)

5、工具本身並無想像力綜上所述,可以歸結自動化完成不了的,手工測試都能彌補,兩者有效的結合是測試品質保證的關鍵。

自動化測試,說白了,就是監視開發有沒有在開發新功能的時候,把老功能弄壞了。 有了自動化,可以做老功能的回歸測試,這樣測試人員就可以花更多的精力測試新feature. 自動化測試的本質是發現變化的東西對不變東西的影響。

我們來看幾個實際的例子: 1、有項目來了,測試小李手工測試與自動化用例同步進行。導致測試排期緊張。這是沒必要的,因為自動化不是要跟上變化的東西,恰恰要測那些不變的東西。

2、老大要求每晚都運行一遍自動化用例或者把用例運行100次,因為他覺得自動化用例運行的越多收益越大。這也是沒必要的,因為不變的東西證明一次和證明一百次的結果是一樣的。

3、某個公司有專門的測試開發職位。其它的業務小組都是獨立的。這個測試開發,就沒有啥活干。可業務小組的手工測試做不完,回歸次次還得手工,業務小組沒法指望測試開發幫忙幹活,他們不是一個組的,測試開發也不知道哪些業務是可以自動化的,也不會下沉到業務小組裡面去。效率一點都沒提升,自動化測試就是個花瓶。

4、某個業務小組準備開展UI自動化,測試A擔當重任。結果追求程式碼的完美,每次還需要code review, 層層封裝,程式碼進展特別緩慢,過不久,整個業務全部重新推倒,case完全沒法用。對領導可以說實現了多少自動化,有多麼漂亮的程式碼,程式碼庫裡面可查。可其他人繼續苦逼的做著手工,就連回歸也一點沒有減輕負擔。

5、某個SQA, 對測試開發說,你給我開發一個系統,要方便我統計品質度量數據,需求么,自己想,一個星期交貨。結果可想而知。

我們對自動化測試的各種偏見,是因為我們對它的定位不準確。 要麼我們將其割裂開來,一個專門的職位,獨立於項目組外。 要麼分配的任務,無法度量並且超過開發的能力。 要麼追求程式碼上的數量,而實際沒什麼效果。

如果寫個小工具,能輔助提高測試效率,算不算自動化測試? 如果寫個程式碼,能造一些測試數據,算不算上自動化測試中的一部分? 其實自動化測試,就是一種測試手段,只是用程式碼來代替人工。 如果你會自動化測試技巧,不去了解業務,就不知如何將手工測試case轉化成自動化測試case. 如果你很精通業務,不了解技術,也就不知道如何能實現將重複的手工測試解放出來。

所以,手工測試和自動化測試是不能分割開的。如果有技術,又做著重複的手工,就一定會思考,如何將其自動化。

手工測試可以轉化為自動化測試,但不是唯一出路。做手工測試的,必須要有將其轉化為自動化的能力。做自動化的,必須有項目業務背景。

自動化應該是審視軟體研發活動的每一個環節,去發現那些可以被工具化自動化的重複性活動,然後去實現。廣義的自動化應該包括但不限於以下環節: 測試環境的搭建和管理 測試環境的檢查,監控和報警 測試程式碼的編譯和測試構建 測試程式碼的靜態檢查和報警 測試用例的分發和執行 測試結果的保存與管理 測試報告的生成 測試優先順序的建議

自動化的成本與收益(ROI)

一個過於簡化的公式可以這樣寫:

自動化的收益 = 迭代次數 * 全手動執行成本 – 首次自動化成本 – 維護次數 * 維護成本

或者如果假設迭代次數和維護次數近似相等,這個在某些情況下可以成立,比如一個比較新的產品: 自動化的收益 = 迭代次數 * (全手動執行成本 – 維護成本) – 首次自動化成本

解讀: 自動化的收益與迭代次數成正比 自動化收益可能為負數:即當自動化成本和維護成本比手動執行成本還高時 很多時候自動化成本並不比手動成本高,但是維護成本很高 為什麼強調過於簡化,因為這裡的自動化收益僅僅考慮時間和資源成本的節省。好的自動化帶來的迭代周期的縮短,是可以縮短項目周期,在某些時候能變不能做為能做,進而帶來的機會收益是巨大的,也是很難量化的。這個就要求決策者對軟體工程和自動化有比較正確的直覺和理解。片面追求自動化的資源節省,或者要求精確量化自動化的收益,本人覺得都不可取。

推論1:什麼項目適合自動化 下面幾種情況比較適合自動化: 回歸測試為主的Support Engineering項目,即需要長期做支援維護的產品。或者有過去版本需要長期做支援維護的產品。這種產品(比如企業軟體,作業系統等)一個版本在發布之後往往需要支援好多年,做bug fix和patch。這個時候每次小版本的開發都會增加迭代次數,並且每次產品變動都非常有限,維護成本相對偏低,自動化收益就非常好。這也是很多企業級軟體或者硬體產品有專門自動化團隊的原因。因為產品的支援維護開發的回歸測試基本靠自動化 介面比較穩定的產品, 手動測試特別費時費力,甚至無法達到測試目的的項目。比如壓力測試,大數據或者大量重複數據測試,必須有自動化工具的支援

推論2:自動化的介入時間點 一個項目的初期可能不太適合自動化。因為項目初期用戶介面和介面沒有穩定,自動化程式碼會被動的被要求頻繁改變,維護成本非常高。自動化收益不好。而反而手動測試能夠快速發現問題,回饋給開發人員。而到了項目後期和維護期,自動化再介入為回歸測試做準備,可以最大化自動化收益。

推論3:自動化的程度和自動化率 這裡自動化的程度是指整個軟體研發活動中引入自動化的程度。推論2中說,有些項目早期可能不太適合高度自動化,但是項目早期仍然可以選定某些環節進行自動化。比如穩定的公用介面,軟體的編譯和部署,環境的搭建等從一開始就比較穩定的部分。

自動化率同樣也要看產品和項目的特性,對於產品的UI部分如果會頻繁改動,可以做比較低的自動化。對於介面比較穩定的服務組件可以提高自動化率。

你有什麼樣的團隊,工具和基礎設施 其實這個因素是做所有事情都必須考慮的。自動化測試本身就是軟體開發。好的自動化測試框架,架構設計很重要。這些會決定自動化的開發成本和維護成本。這些都要求很強的開發能力。如果你的團隊只有很有限的開發能力,那麼怎麼去做自動化,是做最原始的錄製回放,還是數據驅動。複雜自動化也需要良好的基礎設施支援。比如你有很好的DevOps的虛機管理系統,就不用自己去開發,省下的資源和人力也是很可觀的。 工具是另外一塊,如果公司有實力支援商業測試軟體和管理軟體,就可以降低編程要求(當然這會帶來一些其他問題)。如果沒有辦法用商業工具,只能考慮開源和自己開發,這個對自動化測試開發的能力要求就高。總之必須選擇和團隊,技能儲備,基礎設施與工具匹配的自動化策略。

管理層的理解程度和支援 這個就不再展開。我見過很糟糕的情況,一個帶好幾百人兼顧產品技術的VP,越3到4級直接給測試團隊提技術需求和建議。你說是做還是不做,怎麼做?還有一個團隊,自動化測試人員從來沒有寫過Java或者其他OO語言的程式,被要求從頭設計自動化框架,那就是一場災難。還有一個團隊,管理層幾次要求更換自動化工具,相當於整體重寫自動化腳本。

自動化測試是一個很專門化的領域,自動化測試又是對工程師的技術廣度深度要求很高的工作。對於團隊管理和決策者來講,請不要簡單化和孤立看待自動測試。最重要的是確保聽取真正理解產品,團隊和自動化測試的技術人員的判斷。

OK, 以下是用Airtest錄製的微信小程式自動化測試。

自動生成的程式碼如下

# -*- encoding=utf8 -*-  __author__ = "anderson"    from airtest.core.api import *      from poco.drivers.android.uiautomation import AndroidUiautomationPoco  poco = AndroidUiautomationPoco(use_airtest_input=True, screenshot_each_action=False)  from airtest.cli.parser import cli_setup    if not cli_setup():      auto_setup(__file__, logdir=True, devices=[              "Android:///",      ])      # script content  print("start...")  poco("android.widget.LinearLayout").offspring("com.tencent.mm:id/dcj").child("android.widget.FrameLayout").child("android.widget.FrameLayout").child("android.widget.FrameLayout").offspring("com.tencent.mm:id/v").child("android.widget.LinearLayout").child("android.widget.RelativeLayout")[1].offspring("com.tencent.mm:id/jq").click()  poco("android.widget.LinearLayout").offspring("com.tencent.mm:id/dcj").child("android.widget.FrameLayout").child("android.widget.FrameLayout").child("android.widget.FrameLayout").offspring("com.tencent.mm:id/v").child("android.widget.LinearLayout").child("android.widget.RelativeLayout")[2].offspring("com.tencent.mm:id/jq").click()  poco("android.widget.LinearLayout").offspring("com.tencent.mm:id/dcj").child("android.widget.FrameLayout").child("android.widget.FrameLayout").child("android.widget.FrameLayout").offspring("com.tencent.mm:id/v").child("android.widget.LinearLayout").child("android.widget.RelativeLayout")[3].offspring("com.tencent.mm:id/jq").click()  poco(text="京豆").click()  poco("android.widget.LinearLayout").offspring("com.tencent.mm:id/dcj").child("android.widget.FrameLayout").child("android.widget.FrameLayout").child("android.widget.FrameLayout")[1].child("android.widget.RelativeLayout").child("android.widget.FrameLayout")[0].offspring("com.tencent.mm:id/ph").click()      # generate html report  # from airtest.report.report import simple_report  # simple_report(__file__, logpath=True)  

如何看待這種錄製的自動化?個人覺得,在資源缺乏的情況下,這種自動化測試也是很管用的。

為什麼對自動化有這麼多誤解? James Bach 曾經在一篇博文提到,自動化測試這個名字是非常有誤導性的。它讓一般的人誤以為就是測試完全被自動化了,就像一個自動的咖啡機一樣,我只需要把杯子放在那裡,按一個button就夠了。James說更加準確的叫法應該是「工具輔助的測試」。當然他還有另一層意思,就是好的測試用例是沒有辦法100%被自動化的,測試人員的經驗,邏輯判斷和探索性的測試方法都不能被有效自動化。我非常同意這個觀點。

作為管理者,就想有個簡單的KPI考量機制來考核人。所以會指定一些指標來考核。 作為測試人員,也希望自己的工作更加有價值,自己更加具有競爭力,都會覺得自動化測試是一個比手工測試更體面,更有前途的職位。所以自動化測試能力也是衡量體現自己能力的一種表現。

想做有效的管理,就很難繞開度量的問題。在選擇度量指標上,大部分管理者總是傾向於關注容易度量的指標,而忽略難以度量的指標。但是容易度量的指標不一定是重要的,難以度量的反而可能是重要的。 軟體開發產出最直觀的結論就是一行行程式碼,實際上程式碼行數的多少並不代表價值的多少,自動化case的數量並不能說明品質的好壞。當考核不合理導致出現大量的複製,不合理的設計,大量的冗餘,不但難以理解和維護,甚至沒有實際運行起來。這樣就造成大量的時間浪費,同時也造成品質的嚴重腐化。

說了這麼多,提高整個組織的效率才是關鍵。不管你實現了多少自動化,不論你用何種手段實現自動化,測試的宗旨是在有限的時間和資源內,將可能存在的品質風險儘可能早的暴露出來,並且協助開發儘快解決。