【NCTS峰會回顧】中國卓越測試中心陳曉鵬:基于BDD的敏捷測試案例分享
2019年10月26日,由Testin主辦的第二屆NCTS中國云測試行業峰會在京召開,此次峰會以“AI+未來”為主題,匯聚來自國內外測試領域的知名專家學者、領先企業決策者、高層技術管理者、媒體從業者等,共同探討高端云測試技術,幫助測試從業者了解最前沿行業趨勢,及最新的行業實踐。
會上,中國卓越測試中心負責人陳曉鵬做《基于BDD的敏捷測試案例分享》主題演講,陳曉鵬指出,“做自動化測試,一定要跟CICD和DevOps做集成,把從Idea到實施上線到最終交付市場的整條鏈條打通,只有實現業務端的敏捷,自動化測試才能發揮最大的價值。”
以下為陳曉鵬演講實錄:
大家下午好,非常高興能夠參加Testin舉辦的NCTS中國云測試行業峰會,我在北京參加活動比較少,所以先自我介紹,我叫陳曉鵬,目前在某國際TOP3的IT咨詢公司負責中國區測試業務,也就是中國卓越測試中心負責人,現在整個測試團隊規模大概200人服務30-40個國內外項目。我個人的背景很簡單,在測試領域工作18年多,相對來講比較專一,期間沒有換過其它領域。但是從服務的公司性質來講,前6年是在民營企業,后12年是在外企。外企經歷也非常集中,主要在埃森哲、IBM、德勤這三家全球最領先的 IT咨詢公司工作。
我是2008年開始和敏捷結緣。不過在21世紀的前10年CMMI在中國非常火,所以當時雖然接受過敏捷的相關培訓,但總覺得敏捷在中國落地有點難,畢竟當時是CMMI的天下。不過2010年之后敏捷在中國卻發展得紅紅火火。2013年的時候,我在IBM開始接觸 DevOps,然后一直在中國推廣DevOps。我記得第一次做DevOps的講座應該是2013年在深圳科技園,當時很多人連DevOps如何發音、是什么都不知道。不過后來DevOps也發展很快。到如今敏捷也好、DevOps也好,已經在中國如火如荼的發展,每個人都耳熟能詳。
現在如果談敏捷、談DevOps,大家可以在網上搜索到很多很多介紹它們的書籍和資料,但是大家有沒有在網上搜索過關于敏捷測試的書呢?據我所知,現在市面只有兩本比較出名的專門談敏捷測試的書,它們出自同一個美國女性敏捷專家Lisa Crispin。她這兩本書是姐妹篇,已經被中國的譯者翻譯成中文出版。除此之外沒有太多其它敏捷測試相關的書籍了,所以我在2015年開始專門研究敏捷測試這樣一個話題。本來我想在今天下午去分享敏捷測試方法論體系的,但是我看大會上都想聽落地的東西,所以今天下午我給大家帶來了一個實實在在的敏捷測試相關的落地案例分享。
這個項目的客戶是一家娛樂公司,我們在2017年和他們做接觸,客戶已經有了一套會員管理系統,但是該系統比較舊,技術比較落后,但客戶非常有想法也非常激進,他對我們說需要用業界最新的技術、最好的方法、最先進的理念來開發一套新的會員管理系統,這是當時客戶的目標。另外一個客戶的目標是希望在半年內把項目上線,所以這是當時客戶給我們的任務。
我們如何應對呢?通過對項目的風險分析后,我們發現挑戰在于三方面內容,第一是技術方面,客戶說要采用新的IT技術,那么新的IT技術勢必會帶來很大的技術風險。新的技術到底成熟不成熟,有沒有相應的資源懂這些技術,這是一個很大的風險;第二是進度非常緊而質量要求很高,需要在半年內上線所有的功能,把老系統替換掉,用新系統做承接。同時,因為會員管理系統涉及到會員資金管理,大家知道如果系統一旦涉及到金額算錯或者有問題,那勢必帶來非常大的負面影響;第三是采用敏捷測試Scrum加BDD開發模式來開發,在2016年這樣的開發模式還處于很多人在嘗試但還不是很成熟的狀態。
所以,我們當時組成了項目組,大概規模是50人左右,分成5個Scrum Team,每個Team大概8-9人的規模。其中每個Team包含兩個BA,這兩個BA在客戶的香港辦公室駐場,和客戶近距離溝通,獲取客戶需求。剩下6個人都在廣州遠程,有5個人是開發,1個人負責功能測試。除此之外還有兩個Share的測試開發工程師是在不同Scurm Team之間共享的,所以整個項目是40-50人的規模。這個敏捷團隊其實屬于分布式的,因為有香港團隊還有大陸團隊,而且也包含多個Scrum Team。
這個項目的技術架構底層采用了亞馬遜AWS云,上面是mongoDB數據庫,再往上采用容器技術和微服務架構,然后通過暴露的RestfulAPI給到前端,前端用Angular JS來實現,這是技術層的介紹。同時在開發模式上引用了兩個敏捷實踐:一個是Scrum,Scrum大家聽了很多,很多人也都在用Scrum;另外一個是BDD行為驅動開發。這是另一種敏捷實踐,它和Scrum不沖突,而且還可以融合在一起,這就是當時的情況。
從整個項目的技術特點和開發特點,它們會對測試會帶來四個風險:第一個風險是技術風險。在2017年初,很多測試人員都不具備云計算和微服務的知識,在這樣一個技術平臺下要做測試的話,如何保證在新技術下能夠確保質量是第一個挑戰;第二個挑戰是進度風險,計劃整個項目在半年完成上線,同時兩周一次的迭代節奏是非常快的,大家想想兩周時間要有開發還要有測試,節奏怎樣配合確實是非常大的挑戰;第三是質量風險,剛才提到因為系統當中涉及到金額信息,如果計算錯誤會帶來很大的負面影響,所以在質量上也有很大的壓力;第四點是管理風險,在2017年Scrum大家可能比較熟悉了,但是BDD到底怎么玩其實項目也沒有太多的經驗,特別是對測試人員。測試人員怎么融合在整個敏捷的流程里面其實是很大的挑戰。
那么,如何面對這四大挑戰呢?我們當時總結了測試難點后經過分析和尋找對策,最后把它歸納成兩個策略:一個是自動化測試,我稱之為倚天劍;另一個是持續集成,我稱之為屠龍刀。這兩招在現在看來可能不算太新的亮點,但在3年前還算蠻新的一次嘗試了。
關于自動化測試,很多人會講這沒有什么特別的,因為我在項目也在用自動化測試啊。那到底有什么區別呢?我這里講的自動化測試是分層自動化測試的概念,分層自動化是最近這幾年測試的一個流行趨勢。何謂分層自動化?就是指我們做自動化測試不能一直只是往UI層的自動化測試方向發力,為什么不能這樣發力呢?因為UI層的自動化比較脆弱、不穩定,開發和維護成本比較高。前幾年起,包括騰訊等很多大廠都漸漸的不再往UI自動化做投入,而是把測試精力下沉到下一個級別,比如API測試,甚至單元測試。今年上半年我和騰訊手機管家的測試負責人一起聊天,手機管家自動化測試的UI測試只占不到20%,大部分是通過API測試來保證的。可以看到,分層自動化已經是一個趨勢了。無論從風險降低程度,從成本節省程度來講,都應該這么做。所以,在分層自動化這部分,我們當時想的是如何把UI層,API層和單元測試層都覆蓋來減少風險。
關于持續集成,這里我為什么沒有強調DevOps?因為當時在這個項目里Ops運維側不由我們這邊控制,是客戶管控的,所以我們沒有辦法做到端到端閉環的環境。當時我們只是覆蓋到UAT,沒有到運維,所以我們叫做持續集成。
我一直認為,所謂的自動化測試如果拋開CI/CD、拋開DevOps去談,從整個項目來講自動化測試的價值只局限于非常小的部分;做自動化測試,一定要跟CI/CD或DevOps做集成,把從Idea到實施上線到最終交付市場的整條鏈條打通,只有實現業務端的敏捷,自動化測試才能發揮最大的價值。
那么策略是有了但是怎么落地才是最重要的。我們的第一個方式是自動化測試,由于項目開發采用BDD方式,所以自動化框架選擇上我們當然毫無疑問選擇了支持BDD的框架Cucumber。其實Cucumber從我的理解上來講并不能稱之為自動化測試框架,我覺得更多的作用是能夠一個所謂用自然語言編寫的需求能自動翻譯成自動化測試的代碼框架,這是一個非常非常大的好處。如果在座各位年紀和我差不多的話,你一定會聽說過有一個工具ROSE。如果開發出身的話,一定會知道做UML統一建模語言設計,那么統一建模語言設計工具ROSE在2000年左右是所有開發人員必須得學的一個工具。那個工具有一個非常大的好處,就是通過畫UML圖可以自動轉化成代碼框架。其實Cucumber就是和ROSE有異曲同工之妙,可以把自然語言的需求直接翻譯成自動化測試代碼框架。在這種情況下,自動化測試工程師所要做的,就是在代碼框架里填寫業務邏輯和驗證規則就OK了。在某種意義上來講,這能夠提高我們自動化腳本的編寫速度,這就是我們當時采用Cucumber框架的原因。
大家知道在用BDD開發模式時,在需求端要用一個標準化的或者說規定好的語法下來編寫,這個語法我們叫做Gherkin語言,這要求所有需求都要采用一種叫GWT的方式,也就是給我什么樣的場景,什么樣條件下會發生什么樣的一個結果。那么用GWT方式有什么好處呢?如果說我們在需求階段如果用傳統方式去做需求分析的話,一定會涉及到首先需要從業務需求轉變成為系統需求,再從系統需求轉變成開發需求,需求的轉換過程會存在有信息傳遞的損失還有翻譯錯誤的風險。我曾經做過一個項目的咨詢,為某移動公司系統做缺陷分析,一年有400多個上線后缺陷,我當時是一個一個分析后去歸類,發現大概有15%的缺陷是因為需求不明確導致開發理解和需求不一致。通過BDD方式是能夠解決這個問題,因為通過BDD方式在整個項目里只有唯一的需求描述,你看不到還有什么所謂的業務需求、開發需求、系統需求,沒有那么多需求版本了,你只有一份,無論是需求人員,開發人員,測試人員拿到的都是同一份的需求。我覺得BDD最大的好處,就是減少了項目成員對需求理解層面的差異和不一致,完美解決傳統項目里所帶來的需求問題。所以采用了BDD的這個Gherkin語法去描述需求,需求通過Cucumber框架翻譯成自動化測試代碼框架,翻譯完自動化測試工程師只需要寫一些業務代碼邏輯就可以了。
我們當時除了集成UI自動化測試工具之外,還把API接口測試的工具集成進去了,為什么要這么做呢?其實我們想實現所謂分層自動化的能力,也就是說讓框架既能支持UI層自動化,也能支持API自動化,那很多人會問UT單元測試呢?單元測試由開發人員通過Junit去實現。
總而言之,測試金字塔由三個測試層級去做覆蓋。我們基于Cucumber做了大量二次開發的工作,大家會看到原始的Cucumber框架就在這里,就是這么一點的東西,我們在原始Cucumber框架上做了很多二次開發的工作,包括驅動層支持Selenium,HttpClient和Appium等,通過插件方式使得這樣一個自動化平臺不僅僅支持Web、API,還可以支持Mobile。
另外,在上層做封裝。比如我們對元素管理,大家知道做UI的自動化最頭疼的就是對象的改變,對象改變后很多時候必須要調腳本,這使我們做UI自動化的時候,腳本維護上工作量很大,因此,我們也在做很多這方面的改進。這里包括控件優化,還有封裝,配置管理,數據管理等。比如,測試數據可以從數據庫、表格導入;包括異常管理,出現問題以后有自動截屏,自動獲取日志,將信息自動提供給開發人員。再上層集成了Jenkins和email,Jenkins可以做交付流水線編排和管理,能夠使它達到每日構建能力,通過每日構建相當于不光只做UI測試的任務,可以做單元測試、API測試和UI測試三個層級。當然和郵件集成現在很多人說郵件很慢的,所以我們除了郵件還可以做更實時的短信通知,方便出問題以后馬上有人做跟進。
這個框架特點有五個,第一是確保腳本穩定性大大增強,同時使用Cucumber加快自動化測試腳本的開發,縮減了開發時間,提升了效率;第二是通過封裝手段,使得在寫腳本的時候,不用再用Xpath方式去定位對象,這樣操作很慢,我們會用更簡便的識別方式去實現,使得我寫腳本時候可以大大提速;第三是易讀性,Cucumber大家知道用GWT語法寫需求,這個無論開發人員也好,測試人員也好,甚至業務人員都能很容易讀懂你的腳本;第四是易擴展,可以支持APP,WEB;第五是易維護,它有截屏截圖、日志log等來幫助開發定位。這是我們當時在自動化測試方面做的一些工作。
剛才講到的是自動化實踐,但是自動化測試或者說測試如何融入在一個Scrum流程里,我估計在座很多同學可能都有同樣的問題,測試在敏捷環境中到底怎么做?和傳統測試是不是有很大變化?這里我給一個圖,這個圖相對來講比較簡單,但我們為了這個流程圖足足花了兩個月的時間才摸索出來,是實實在在通過項目實踐摸索出來的。
如果大家了解Scrum,我們在每一個Sprint開始時,肯定會有迭代計劃會,在計劃會的時候,所有的相關人員都需要參加,無論是BA,行業SME,開發測試人員都要參加。參加完這個計劃會后,會確認本次計劃會做哪些用戶故事。確認用戶故事后,開發人員會進行開發構建和單元測試。測試人員做什么呢?測試人員會做ET,探索式測試。測試開發工程師做什么呢?首先會看本次用戶故事是否能夠做自動化測試,如果不行的話就停止,如果可以的話就需要做自動化測試準備。
其中大家看到自動化測試任務進度條被迭代結束時間線分成兩邊,也就是自動化測試任務跨了兩個迭代。自動化測試任務和其它任務比起來偏后了。為什么會偏后?因為我們當時摸索出來一個經驗,就是自動化測試會在第二周星期三開始才真正做自動化腳本開發。為什么會這樣呢?因為我們當時發現,在最開始做自動化腳本開發的時候,因為那時開發人員還沒有想好想法,在開發過程中會看到界面變來變去,前端非常不穩定,那么這個時候你做腳本開發的時候,你會發現需要跟著經常調整,這種情況下會浪費自動化工程師的很大精力。所以我們當時是等到相對穩定的時候再去做自動化腳本的開發,這就是為什么會在第二周的周二或者周三開始做腳本的開發。而自動化測試任務的完成就要到下一個迭代的第一周周三左右的時間了,這就是為什么自動化測試任務跨了兩個迭代。
在座可能有些人會問本次迭代自動化測試沒有完成那怎么保證質量?因為本次Sprint的質量會有這個功能測試人員通過做探索式測試來保證,而本次之前的Sprint質量是通過執行自動化回歸測試的時候去覆蓋,也就是N-1的迭代質量是自動化回歸搞定,第N迭代質量由探索式測試搞定,所以沒有什么問題。等到N+1迭代時,會把N迭代開發好的自動化腳本加到下一次回歸用例庫里,又變成下一個輪回了。這是我們摸索幾個Sprint以后總結出來的,是一個關鍵點。
剛剛講到的是自動化測試解決方法,我們實現了分層次自動化,實現API和UI自動化。接下來我們把它融合在集成的CI/CD場景里面,這是我們CI/CD的集成場景,可以看到開發人員寫完代碼以后不會直接提交到代碼配置庫里,會在本地先做代碼掃描,然后做開發的JUnit單元測試,沒有問題了才把代碼提交到GIT里。提交到GIT后由CI/CD流程做保障。Jenkins開始構建,Jenkins先做服務端的代碼掃描,因為剛才做的是本地端的。做完服務端代碼掃描,然后做Docker部署,做完部署后首先先觸發Cucumber做API測試,然后再觸發Cucumber做UI測試。大家想為什么有先后順序?因為API執行效率最高,執行一個API接口的測試一兩秒就已經能夠得到結果了,然后跑一個UI腳本可能需要幾分鐘。所以一般來說我們通過先做API,API沒有問題了才往UI層做自動化,如果API有問題就停止,然后去解決,跑完UI后沒有問題了,再通過人工做探索式手工測試。手工測試如果發現問題,那么就提交Bug,然后回到前面開發人員去修改代碼和單元測試,所以這是一個持續集成的工具鏈,通過這樣一個場景能夠使得整個效率在兩周之內把它測試完,而且兩周之內確實能夠測試完,這就是整體的集成測試場景。
另外我想補充一點,有些人以為只要把工具鏈搭建好了就實現了DevOps,這是理解有誤。我們所說的DevOps不僅僅只是一條工具鏈,DevOps除了工具上的實施之外還有很多方面,包括人、組織、流程,這些方面都需要做改變才能夠真正實現。
下面這個是一個持續集成的截圖過程,會看到我們在Jenkins里做配置,每日自動觸發,然后下面是自動化測試報告,會有不同的執行結果狀態,還有運行日志和記錄截圖,每天把信息通過郵件或者溝通,短信當然沒有那么詳細,只是有問題的時候通過短信通知,比如說半夜會通知。但是郵件就比較詳細,每一個開發人員早上來了以后發現有郵件點擊開就可以看到問題,馬上就可以進行修復。
綜上所述,整個項目我總結有三個收獲:第一是實現全棧式自動化測試,從單元測試、到API測試,再到UI測試,測試金字塔都覆蓋到了。單元測試是開發人員做,但是通過Jenkins集成。我們當時做的API自動化測試覆蓋率達到80% ,UI覆蓋率達到65%;第二個是我們當時在這樣一個所謂比較新的技術環境下,整個項目的質量得到保證,我剛才也介紹了我們怎么通過自動化一步步保證質量,減了上線后的缺陷,我們這個項目上線以后缺陷很少。所以節省很多返工工作量;第三是遵循了BDD和Scrum開發模式,開發人員測試人員緊密合作互相配合,使整個速度加快。所以整個案例是是結合了敏捷Scrum和真正使用BDD方式再結合自動化、結合CIC/D的整個過程,這就是我今天想給大家分享的實戰案例。