現在對于自動化測試與CI往往有一些很常見的謬見,包括一些專門從事相關工作的人都未必清楚。在實際的工作中感觸頗深,所以想撰文討論一下。
第一,自動化測試就是給CI服務的,或者自動化測試不太能發現問題。
持有這種觀點的人,建議他們去看看Google或者Microsoft的相關測試研究的文章,或者GTAC( Google Test Automation Conference),也許可以拓寬我們考慮這個問題的思路。
他們的測試對象是搜索引擎,海量的數據庫信息,或者提供的各種服務,比如Google Map,Navigation。他們研究的是搜索引擎對于海量的數據庫處理起來是否有效,搜索結果是否準確 。
下面舉幾個例子:
比如Google會提供一種 ‘Auto Completion'的功能,你只要在搜索框里敲入一個詞,google會根據與這個詞的相關性大小,以及該關鍵詞被搜索的熱度,自動補全一些關鍵詞,并提示給你。這樣,你就可以參考或者直接用別人的搜索條件。那大家有沒有考慮過,這種功能應該如何測試呢?
還有導航系統,怎么確保從A點到B點找出來的路徑都是正確的呢?而不是說你要找一個當地的餐館,導航卻告訴你要來一次跨國旅行呢?
面對這些海量的測試數據,并且基本上也無法預先給不同的測試數據定義好期望的測試結果。所以他們無法采用我們這樣的靜態的自動化測試,而且通常Manual Testing也無法幫助他們解決問題, 他們必須采用動態的大規模的自動化測試,或者叫計算計輔助測試。
他們的做法就是采取一種叫HBT( Heuristics Based Testing)的技術,測試工程師找出一些測試是否成功的判斷法則,而不是像傳統的自動化測試一定要明確規定靜態的期望結果,并把這種判斷規則用代碼實現。
通過這種方法,再加上一些并行的測試技術,他們也許一天可測上千萬個case,并且在一種判斷法則已經不太能有效地發現問題的時候,可以隨時調整或者尋找新的判斷成功與否的法則。
而尋找 “測試是否成功的判斷法則”,也就是常說的Test Oracle的時候,則很類似傳統手工測試做manual exploratory testing的過程。測試人員做手工測試的時候,不是重復地去敲鍵盤,點鼠標,而是尋找系統的失效模型,然后利用自動化測試技術實現,并把這個失效模型放大到盡可能大的范圍。 這部分工作,往往是測試工作中最有意思,最有創造性,往往也是最考測試人員功力的。
我曾經看過一個他們的例子,Microsoft 的Principal Test Engineer寫的,他們用這種方法,一天執行了2200萬個測試用例,發現了20多個可能的問題,然后和相關stakeholder討論。
從上面的例子可以看到,Test Automation其實完全不受限于CI這種模式的下的測試,完全可以借助自動化測試的手段來做Exploratory Testing.
第二:CI中的測試一定要保證測試的全覆蓋。
首先,測試的全覆蓋本來就是一個偽命題,從來也沒有一種測試可以做到全覆蓋。測試人員要解決的是在測試設備有限,測試人員有限,測試時間也有限的情況下,如何能夠讓組織在測試的投入上,達到最高的ROI。
然后回到CI,我們來看一下CI的目的到底是什么。
在傳統的開發模式下,軟件組織在Integration的時候往往會發現模塊的接口定義或者理解有不一致,然后需要返工,甚至因此要改模塊的內部設計。在各個模塊都各自完成以后,想讓他們在一起能工作,給客戶提供一個完整的功能,往往還要等待很長的時間
既然集成這么麻煩,那我們就提倡盡早集成,盡快測試,以期待盡快發現問題。同時開發人員在實現代碼的時候,如果能夠盡快給他們的實現提供反饋,這對他們避免在后來的開發中犯同樣的錯誤,也是非常重要的。如果這種反饋的成本比較低,那我們就可以讓這種反饋盡可能頻繁。
具體來說,如果讓盡可能多的測試都自動化了,那我們在降低反饋的成本上就走出了第一步,也是非常重要的一步。
但是大家要思考一下,反饋的速度,頻率和反饋的價值是不是完全等同?
開發人員的開發過程其實就是一個不斷犯錯誤,又不斷糾正的過程。
比如說IDE會頻繁告訴他們的一些語法錯誤,然后在編譯鏈接的時候又會發現一些問題,然后在執行UT的時候又會發現一些問題,然后在后面的Smoke Testing,Function Testing,System Testing又會得到一些反饋,然后從最終的客戶那里會得到更進一步的反饋。
隨著軟件技術的發展,比如更好的IDE,更好的UT,更好的自動化測試,開發人員在不斷地降低得到反饋的成本,提高反饋的效率。但是,我們可以問問周邊的開發人員,特別是那些資深的開發人員,在他們的開發生涯中,讓他們印象最深的一個Bug,是怎么發現的?
我會懷疑讓開發人員得到的一個印象很深的Bug,一個真正有價值的反饋,往往是一個好的測試人員給他的。
在我們的組織里,一個好的測試人員是很受開發人員尊重的,因為他不光光是發現產品Bug那么簡單,他還不斷地給開發人員提供有價值的反饋,不斷地讓開發人員以該更加周全思路來考慮問題,也促使開發人員不斷地成長。
但是CI模式下完全依賴機器的執行,不強調人的介入的自動化測試,會是給開發人員提供反饋的唯一途徑嗎?
通過我們的經驗來看:
1. 有些team抱怨這種模式的測試,我們也叫CRT( Continuous Regression Test)基本發現不了軟件問題。
2. 個別Team的經驗是CRT可以幫助他們發現很多問題,但估計和模塊工作的領域有關,比如該模塊本身就是問題比較多的模塊。
3.即便是上述第2種情況的模塊,也發現許多軟件深層次的問題,比如一些設計上考慮不太周到的地方,往往也是一些Senior Tester才能發現的。
4.往往一個測試中發現的問題,在另外一些測試用例里面會被重復發現。意味著我們的測試用例發現問題的能力往往是有冗余的。
在這種情況下,再強調在CI的模式下要保證測試的全覆蓋,我們來看一下會給我們帶來什么。
首先,你的測試用例越加越多,你的測試周期勢必越來越長,也就無法給他們提供及時的反饋。而CI的精華之一就是強調給開發人員提供及時的反饋。
其二, 如果你考慮并行測試的話,勢必要增大測試設備的投入。在電信領域,測試設備往往是很貴的,往往比請幾個測試人員還貴。當你的自動化測試不能持續給開發人員提供有價值和有深度的反饋,你還不斷要求管理層給你加大測試的投入,往往也是不現實的。根據我們的經驗,很多采用靜態測試技術的自動化項目,往往都會碰到類似的問題。
所以CI天生是用來解決Integration的問題的,因為Integration給軟件開發帶來了很多的問題,是開發工作中很大的一個bottleneck,所以采取了Continuous Integration的方式去做。而Test Coverage則是測試中另外一個很難解決的問題,意指在測試階段盡可能保證全面的測試覆蓋,以避免軟件Deploy到客戶現場,被客戶發現問題。CI作為一種很好的Practice,應該被我們很好地應用,但是如果片面追求CI的Test Coverage,反而有可能會喪失掉CI本身的優勢。