■中國農(nóng)業(yè)銀行研發(fā)中心 劉躍光 馮 瑤
隨著金融系統(tǒng)軟件復(fù)雜度的持續(xù)提升,傳統(tǒng)的基于人對業(yè)務(wù)理解的經(jīng)驗型測試方法面臨著巨大的挑戰(zhàn)。由于敏捷迭代引起的回歸測試工作量遠(yuǎn)超瀑布模式,開發(fā)與測試崗位技能不同,以及測試過度依賴人的經(jīng)驗等原因,功能測試的充分度越來越難以保證。在此背景下,金融系統(tǒng)軟件測試及開發(fā)過程中存在如下問題。
一是開發(fā)人員與測試人員之間的交互和溝通存在壁壘。在功能測試階段,測試人員通過黑盒測試方法對待測系統(tǒng)進(jìn)行測試,由于無法知曉程序內(nèi)部邏輯,通常發(fā)現(xiàn)缺陷的處理流程是:測試人員發(fā)現(xiàn)缺陷后向開發(fā)人員反饋,由開發(fā)人員進(jìn)行問題復(fù)現(xiàn),通過debug等方式找到故障代碼段。在這個過程中,由于開發(fā)和測試人員的崗位技能和知識儲備不同,雙方通常需要反復(fù)溝通才能定位缺陷,查找和修復(fù)缺陷的成本高。
二是回歸測試的精準(zhǔn)性難以保證。在項目測試中,修改項目代碼后,往往需要對關(guān)聯(lián)的測試案例進(jìn)行回歸測試。然而,如何找到關(guān)聯(lián)度最高的測試案例,往往需要通過人工篩選來判斷,回歸測試的準(zhǔn)確度高度依賴于測試人員的經(jīng)驗。
三是黑盒測試的充分性難以衡量。功能測試往往采用黑盒的方式實施,在測試過程中,測試人員無法直觀地看到測試用例與代碼的關(guān)聯(lián),以及用例對源代碼的覆蓋程度,測試充分性缺乏明確的度量指標(biāo)作為依據(jù)。功能用例設(shè)計容易產(chǎn)生遺漏,很難發(fā)現(xiàn)代碼中隱藏的缺陷。
四是測試執(zhí)行結(jié)果可信度較低。現(xiàn)有功能測試的人力投入大,但測試經(jīng)理并沒有一種有效手段去獲取測試人員的測試記錄。所以,亟待一種能夠真實記錄測試執(zhí)行過程的輔助監(jiān)控手段,可以向測試經(jīng)理給出可信的數(shù)據(jù)分析結(jié)果,防止偽造和篡改測試執(zhí)行數(shù)據(jù)帶來的測試管理困難。
精準(zhǔn)測試是一種應(yīng)用于黑盒測試方法的代碼級測試覆蓋技術(shù),與傳統(tǒng)的白盒測試開展代碼覆蓋測試不同,它將黑盒測試和白盒測試進(jìn)行了有機(jī)結(jié)合,通過獲取測試用例和代碼邏輯之間的關(guān)聯(lián)信息,可以獲得白盒測試級的代碼覆蓋率數(shù)據(jù),并實現(xiàn)雙向追溯統(tǒng)計,從而達(dá)到“精準(zhǔn)測試”的目的。這個“精準(zhǔn)”主要體現(xiàn)在:一是在測試執(zhí)行過程中,獲取和收集底層代碼運行數(shù)據(jù),能夠可視化地看到代碼執(zhí)行情況(代碼執(zhí)行充分度),進(jìn)而為補(bǔ)充或減少冗余用例提供依據(jù)。二是通過對變更代碼的識別,可精準(zhǔn)圈定需要回歸測試的用例范圍。三是對發(fā)現(xiàn)的缺陷,通過測試用例可間接實現(xiàn)對代碼的精準(zhǔn)定位,在此過程中,需要用到統(tǒng)計代碼覆蓋率、代碼插樁、連接代碼和測試用例、測試用例智能選取、智能缺陷定位等技術(shù)。
1.代碼覆蓋率。代碼覆蓋率是指,至少被執(zhí)行了一次的條目數(shù)占整個條目數(shù)的百分比。最常用的度量代碼覆蓋率有四種方式。
(1)語句覆蓋:又稱行覆蓋。語句覆蓋率指已經(jīng)被執(zhí)行到的語句占總可執(zhí)行語句的百分比。這是最常用也是要求最低的覆蓋率指標(biāo)。實際項目中通常會結(jié)合判定覆蓋率或者條件覆蓋率一起使用。
(2)判定覆蓋:又稱分支覆蓋,用以度量程序中每一個判定的分支是否都被測試到了,即代碼中每個判斷的取真分支和取假分支是否各被覆蓋至少一次。比如,對于if(a > 0 && b > 0),就要求覆蓋a > 0 && b > 0為True和FALSE各一次。
(3)條件覆蓋:是指判定中的每個條件的可能取值至少滿足一次,度量判定中的每個條件的結(jié)果True和FALSE是否都被測試到了。比如,對于if(a > 0 && b > 0),就要求a>0取True和FALSE各一次,同時要求b>0取True和FALSE各一次。
(4)路徑覆蓋:路徑覆蓋率=被執(zhí)行到的路徑數(shù)/程序總路徑數(shù)。路徑覆蓋的目標(biāo)是選取足夠多的測試數(shù)據(jù),使程序的每條可能路徑都至少執(zhí)行一次。路徑覆蓋是覆蓋率最高的一種覆蓋技術(shù)。但對于復(fù)雜的程序來說,路徑數(shù)量巨大,要測試每條路徑既困難又費時,幾乎是不可能達(dá)到100%的。
統(tǒng)計代碼覆蓋率的根本目的是找出潛在的遺漏測試用例,并有針對性地進(jìn)行補(bǔ)充,同時還可以識別出代碼中那些由于需求變更等原因造成的不可達(dá)的廢棄代碼。我們通常希望代碼覆蓋率越高越好,代碼覆蓋率越高越能說明測試用例設(shè)計是充分的,但測試的成本也會隨著代碼覆蓋率的提高以類似指數(shù)級的方式迅速增加。
2.代碼插樁技術(shù)。實現(xiàn)代碼覆蓋率統(tǒng)計的最基本的方法就是代碼插樁。代碼插樁就是在被測代碼中自動插入用于覆蓋率統(tǒng)計的探針代碼,并保證插入的探針代碼不會給原代碼帶來任何影響。根據(jù)插樁對象的不同,可以分為源代碼插樁、中間代碼插樁、二進(jìn)制代碼插樁三大類。
源代碼插樁是通過對代碼源文件插入探針進(jìn)行詞法和語法分析。這種方式對應(yīng)用的源碼有侵入式更改。業(yè)界比較成熟的源代碼插樁工具有GCT等。
中間代碼插樁是對如Java編譯后生成的.class等中間代碼文件進(jìn)行插樁。首先對中間碼文件進(jìn)行分析,確定需要插樁的位置,再將探針插入到這個文件中。業(yè)界比較成熟的工具有Jacoco、Emma等。
二進(jìn)制代碼插樁是對程序真正運行的目標(biāo)文件進(jìn)行探針插入操作。業(yè)界比較成熟的工具有XDebug等。
3.構(gòu)建測試用例與代碼關(guān)系。測試人員在進(jìn)行黑盒測試的過程中,精準(zhǔn)測試工具捕獲測試用例步驟關(guān)聯(lián)的函數(shù)和相應(yīng)的調(diào)用關(guān)系信息,將測試用例、用例相關(guān)函數(shù)信息、關(guān)聯(lián)函數(shù)調(diào)用關(guān)系信息存儲起來形成知識庫。而形成知識庫的過程,對測試人員和開發(fā)人員來說是透明的。構(gòu)建測試用例與代碼關(guān)系的過程見圖1。
圖1 構(gòu)建測試用例與代碼關(guān)系
4.回歸測試用例精準(zhǔn)選取。測試用例智能選取可根據(jù)程序的變動情況對測試用例的優(yōu)先級進(jìn)行分析和打分,篩選出優(yōu)先需要執(zhí)行的重要用例。使用智能回歸測試用例選取功能算法的前提是至少需要兩個插樁版本的應(yīng)用程序。在回歸測試用例選取的時候,會對比選中的工程版本對應(yīng)的代碼,分析代碼版本涉及的函數(shù)變化,進(jìn)而通過函數(shù)與測試用例的對應(yīng)關(guān)系,推導(dǎo)出涉及到的測試用例,從而實現(xiàn)回歸測試用例的自動選取,大大減少回歸測試的時間及風(fēng)險。
5.測試缺陷精準(zhǔn)定位。測試發(fā)現(xiàn)的缺陷通常是由開發(fā)人員來進(jìn)行分析和定位的,而精準(zhǔn)測試則通過測試用例和代碼建立的關(guān)聯(lián)關(guān)系,能夠?qū)⑷毕輰?yīng)代碼出錯位置直接定位出來,這相當(dāng)于增加了測試數(shù)據(jù)和測試過程的本身價值。因為精準(zhǔn)測試技術(shù)可以獲知每個用例執(zhí)行的詳細(xì)路徑信息,如果測試人員告知用例狀態(tài)(例如是否通過、是否正確),那么精準(zhǔn)測試算法就會根據(jù)正確和失敗的路徑進(jìn)行差異計算 ,給出缺陷出現(xiàn)具體位置的可疑度排名,這對于測試人員來說,只要找到類似的輸入,程序在輸出上有對錯區(qū)分用例,就可以實現(xiàn)智能定位缺陷功能。
首先使用一個前置編譯器,對某金融系統(tǒng)的被測代碼進(jìn)行靜態(tài)分析和代碼插樁,其中靜態(tài)分析會產(chǎn)生程序的結(jié)構(gòu)數(shù)據(jù)(例如控制流數(shù)據(jù))以及符號信息(PBD文件)并進(jìn)行存儲,經(jīng)插樁后的代碼通過原有編譯系統(tǒng)編譯后,發(fā)布到被測環(huán)境。其次,測試人員通過精準(zhǔn)測試客戶端運行測試用例,采集器就可以接收每個用例對應(yīng)的代碼執(zhí)行數(shù)據(jù),并記錄采集到的插裝代碼發(fā)送的程序運行邏輯編號信息。這些編號和靜態(tài)分析產(chǎn)生的符號信息是一一對應(yīng)的,即通過客戶端執(zhí)行完測試用例后就可以達(dá)到測試用例和代碼關(guān)聯(lián)數(shù)據(jù),該數(shù)據(jù)支持正反向查詢。最后,可對測試用例運用深度分析、缺陷定位、用例聚類分析、回歸測試用例選取、最小測試用例集合等功能,以報表形式展示測試生成的數(shù)據(jù),導(dǎo)出測試報告。精準(zhǔn)測試的實踐過程見圖2。
圖2 精準(zhǔn)測試實踐過程
通過精準(zhǔn)測試技術(shù)的應(yīng)用實踐,可總結(jié)出以下優(yōu)點:
1.通過精準(zhǔn)測試技術(shù)可提升測試的充分性。精準(zhǔn)測試技術(shù)可建立代碼與測試用例的關(guān)聯(lián)。通過運行測試用例,可以查看代碼覆蓋率,得到精準(zhǔn)的量化數(shù)據(jù)。測試人員在完成測試后,開發(fā)人員根據(jù)精準(zhǔn)測試得到的量化數(shù)據(jù)總結(jié)程序中的未覆蓋功能點列表,然后由測試人員補(bǔ)充編寫測試用例并執(zhí)行。通過重復(fù)此過程來提高測試的充分性。
2.實現(xiàn)了可信的測試管理模式。目前,常規(guī)的測試管理方式是人為錄入數(shù)據(jù),數(shù)據(jù)本身的真實性無法保證。而精準(zhǔn)測試的底層數(shù)據(jù)來自于執(zhí)行測試用例時代碼執(zhí)行數(shù)據(jù)的采集,通過專用接口上傳,無法被篡改和偽造。精準(zhǔn)測試技術(shù)提供的可信測試管理模式非常適用于金融公司對第三方測試團(tuán)隊的管理,在一定程度上解決了測試的真實性問題。
3.可快速定位缺陷所在的代碼段,節(jié)省缺陷修復(fù)時間。測試人員發(fā)現(xiàn)缺陷后,不需要再使用傳統(tǒng)方式向開發(fā)人員說明缺陷出現(xiàn)的場景、數(shù)據(jù)、環(huán)境等信息,開發(fā)人員也不需要在開發(fā)環(huán)境復(fù)現(xiàn)和調(diào)試。使用精準(zhǔn)測試技術(shù),開發(fā)人員可以直接看到測試發(fā)現(xiàn)缺陷時的代碼執(zhí)行邏輯,并基于此直接定位問題,交互流程和步驟都大為簡化。
4.可識別有改動的代碼段,更好地開展回歸測試。對于敏捷迭代的項目,可識別出每次迭代的變動代碼,從而選取出相關(guān)的測試用例,節(jié)省了回歸測試時間,提高了測試效率。
精準(zhǔn)測試較傳統(tǒng)功能測試在方法上有很大突破,但從技術(shù)層面看,該技術(shù)還處于發(fā)展初期,并不是完美的,通過應(yīng)用和實踐,也發(fā)現(xiàn)有以下不足:
1.對于架構(gòu)較為復(fù)雜以及涉及眾多外圍系統(tǒng)的金融系統(tǒng)項目,插樁和部署采集精準(zhǔn)測試數(shù)據(jù)的監(jiān)控工具難以實現(xiàn)。通常金融單位部署程序和插樁操作涉及多部門人員,復(fù)雜系統(tǒng)由于跨部門、跨平臺、無權(quán)限、應(yīng)用服務(wù)器數(shù)量眾多等原因,實施起來難度較大。
2.目前對金融系統(tǒng)常用的技術(shù)語言支持有限,不支持C#、node.js、Python等類型的項目。
3.實踐應(yīng)用工具是通過源代碼插樁方式,屬于侵入式插樁,且需將源代碼下載到客戶端所在機(jī)器,才能查看測試用例和源代碼對應(yīng)關(guān)系,這對于保密要求較高金融軟件,存在源碼安全管理方面的風(fēng)險。
源代碼插樁方式對于待測的程序進(jìn)行了修改,不能做到投產(chǎn)程序與測試程序的統(tǒng)一。同時,由于插樁操作過程可對源代碼進(jìn)行查看,因此保密性較差。中間代碼插樁和二進(jìn)制代碼插樁的前提是對目標(biāo)代碼進(jìn)行詞法、語法分析,由于目標(biāo)代碼不是源代碼,語法、語義信息并不完整,所以,相較源代碼插樁方式來講,中間代碼插樁和二進(jìn)制代碼插樁的技術(shù)難度更大。但由于中間代碼插樁和二進(jìn)制代碼插樁對源代碼不可見并且沒有侵入性修改,符合金融系統(tǒng)代碼保密性要求和“所測即所投”的理念。因此,在技術(shù)允許的前提下應(yīng)優(yōu)先使用中間代碼插樁或二進(jìn)制插樁方式進(jìn)行金融系統(tǒng)的精準(zhǔn)測試。
DevOps遵循精益思想,關(guān)注研發(fā)技術(shù)管理標(biāo)準(zhǔn)化,倡導(dǎo)工具賦能、融會貫通。將精準(zhǔn)測試技術(shù)相關(guān)工具納入DevOps實施流水線,將改變測試案例與代碼孤立的現(xiàn)狀,促使開發(fā)測試緊密銜接,達(dá)到工具貫通、流程貫通、數(shù)據(jù)貫通的效果,可強(qiáng)化質(zhì)量管控,提升測試自動化水平。
現(xiàn)在越來越多的項目使用敏捷開發(fā)模式,由于程序版本迭代很快,通常在某個版本上采集少量覆蓋率數(shù)據(jù)后,新的程序版本就發(fā)布了,在此情況下使用傳統(tǒng)的白盒測試工具就無法直接統(tǒng)計到新程序版本的覆蓋率數(shù)據(jù),此時可以借助精準(zhǔn)測試中的累計覆蓋率來解決這個問題,將多個版本的代碼覆蓋率以最新版本的代碼結(jié)構(gòu)進(jìn)行投影并在控制流上進(jìn)行累加。測試團(tuán)隊可以結(jié)合每個版本的覆蓋率以及完整測試周期內(nèi)所有程序版本的累計覆蓋率為參考,來保證項目測試的充分性。
精準(zhǔn)測試工具應(yīng)支持金融系統(tǒng)中多種編程語言,如 Rule、C#、Python、Node.js、Scala、Go 等,以便為更多的復(fù)雜應(yīng)用系統(tǒng)提供自動化測試解決方案。
在數(shù)字化轉(zhuǎn)型時代背景下,金融科技及金融產(chǎn)品創(chuàng)新與迭代加速,分布式、微服務(wù)、集群化的IT架構(gòu)給軟件測試帶來了前所未有的挑戰(zhàn),通過測試技術(shù)、測試方法創(chuàng)新來應(yīng)對這些挑戰(zhàn),無疑是正確和可行的措施之一。精準(zhǔn)測試將黑盒測試與白盒測試進(jìn)行了有效結(jié)合,解決了傳統(tǒng)測試的一些痛點,能夠有力地提高測試質(zhì)量和效率,是值得推廣和應(yīng)用的。
展望未來,在精準(zhǔn)測試的基礎(chǔ)上,實現(xiàn)智能(AI)測試也是可期和可以實現(xiàn)的。軟件測試從手工測試→自動化測試→測試自動化→精準(zhǔn)測試→智能測試,是一個逐漸演進(jìn)的過程,在這個過程中,測試人員所需要做的就是提升能力,擁抱變化。