騰訊云 AI 代碼助手:單元測試應(yīng)用實(shí)踐

引言

在軟件開發(fā)這一充滿創(chuàng)造性的領(lǐng)域中,開發(fā)人員不僅要構(gòu)建功能強(qiáng)大的軟件,還要確保這些軟件的穩(wěn)定性和可靠性。然而,開發(fā)過程中并非所有任務(wù)都能激發(fā)創(chuàng)造力,有些甚至是重復(fù)且乏味的。其中,編寫單元測試無疑是最令人頭疼的任務(wù)之一,它雖然對于驗證軟件組件是否按預(yù)期工作至關(guān)重要,但其編寫過程卻常常讓開發(fā)人員感到枯燥和疲憊。

理想的情況是,開發(fā)人員在編寫代碼的同時編寫單元測試。但是編寫單元測試是軟件開發(fā)中的繁瑣工作,會占用開發(fā)人員大量時間。并且開發(fā)人員在手動編寫復(fù)雜代碼庫的單元測試時可能會犯錯。因此,很多軟件缺乏足夠的單元測試,這使得代碼難以維護(hù)。如果沒有單元測試,出現(xiàn)問題后定位問題就如同大海撈針,這不僅增加了維護(hù)成本,也降低了軟件的可靠性。

在這樣的背景下,AI代碼助手應(yīng)運(yùn)而生,它通過大模型輔助生成代碼來減輕開發(fā)人員在單元測試編寫上的負(fù)擔(dān),提高開發(fā)效率,同時確保軟件質(zhì)量。它將如何幫助開發(fā)人員克服單元測試的挑戰(zhàn),是我們接下來要探討的主題。

一、??? 單元測試概述

單元測試專注于程序中的最小可測試單元,這通常包括函數(shù)、類的方法或模塊等。其核心目的是確保這些基本單元能夠正確執(zhí)行特定的功能,并妥善處理各種邊界條件和異常情況。單元測試的目的是確保這些基本組成單元按照預(yù)期工作,能夠正確地執(zhí)行特定的功能,并且能夠妥善處理各種邊界條件和異常情況。

單元測試一般情況下需要符合如下特點(diǎn):

自動化:單元測試由開發(fā)人員編寫,并使用自動化測試框架運(yùn)行,能夠快速反饋測試結(jié)果,提高測試效率。

隔離性:每個單元測試獨(dú)立運(yùn)行,將被測試單元與其他代碼隔離,確保測試的準(zhǔn)確性和可靠性。

針對性:每個測試用例都針對代碼中一個具體的、明確的行為,確保測試的精確性和有效性。

重復(fù)性:單元測試可以頻繁重復(fù)運(yùn)行,尤其是在代碼修改后,以確保新修改沒有引入錯誤。

及時反饋:單元測試能夠快速發(fā)現(xiàn)錯誤并定位問題,提高開發(fā)效率和軟件質(zhì)量。

單元測試一般會包含以下類型:

函數(shù)測試:驗證函數(shù)或方法在給定輸入下是否返回預(yù)期的輸出。這包括測試各種正常的輸入值,以確保函數(shù)按照預(yù)期工作

邊界條件測試:測試函數(shù)或方法在輸入值達(dá)到邊界或極限情況下的行為。例如,對于一個接受整數(shù)輸入的函數(shù),邊界條件測試應(yīng)該包括測試最小值、最大值、以及接近最小值和最大值的數(shù)值。這可以幫助發(fā)現(xiàn)函數(shù)在處理極端情況時的錯誤

異常處理測試:測試函數(shù)或方法在遇到異常情況(例如無效輸入、錯誤參數(shù)或資源不足)時的行為。這包括測試函數(shù)是否能夠正確地處理異常,并返回適當(dāng)?shù)腻e誤信息或采取相應(yīng)的補(bǔ)救措施

Mock?測試:使用模擬對象來代替真實(shí)的依賴項(例如數(shù)據(jù)庫連接或外部API),從而隔離被測單元,并確保測試結(jié)果的可靠性。這對于測試依賴于外部資源的函數(shù)或方法非常有用,因為它可以避免測試結(jié)果受到外部因素的影響

數(shù)據(jù)驅(qū)動測試:使用一個數(shù)據(jù)表來驅(qū)動測試用例的執(zhí)行。測試用例的輸入數(shù)據(jù)和預(yù)期輸出數(shù)據(jù)都存儲在數(shù)據(jù)表中,測試程序會讀取數(shù)據(jù)表中的數(shù)據(jù),并自動執(zhí)行測試用例。這可以減少測試代碼的冗余,并提高測試效率,尤其是在需要測試大量不同輸入值的情況下

?在實(shí)際的開發(fā)場景中,需要結(jié)合業(yè)務(wù)的真實(shí)需求,選擇合適的測試類型,來確保代碼質(zhì)量和功能正確性。

二、 AI 在單元測試中的應(yīng)用

以下是 AI 代碼助手在單元測試中的應(yīng)用實(shí)踐:

代碼補(bǔ)全與單元測試生成:? AI 代碼助手基于上下文理解,能夠自動推薦最可能的代碼片段,包括方法調(diào)用、變量聲明、循環(huán)結(jié)構(gòu)等。此外,它還能根據(jù)現(xiàn)有代碼結(jié)構(gòu),自動生成對應(yīng)的單元測試案例,確保代碼變更時功能的穩(wěn)定性。

可以通過對話框中的 /test 生成單元測試,或者使用 IDE 編碼區(qū)域中使用每個功能方法的快捷鍵“生成測試”來生成該方法的單元測試。

多輪對話優(yōu)化測試用例: 開發(fā)者可以通過多輪對話,告訴 AI 更多的信息,讓生成的單元測試內(nèi)容更符合業(yè)務(wù)預(yù)期。例如,可以指定業(yè)務(wù)邊界條件、特殊的異常處理邏輯、數(shù)據(jù)處理方式等。

對于生成的內(nèi)容,如果有額外的測試場景需求,可以通過對論對話追加提問。

AI 代碼助手的對話模型會識別用戶意圖結(jié)合上下文對話內(nèi)容優(yōu)化單元測試結(jié)果。

一鍵應(yīng)用單元測試內(nèi)容: 通過對話框結(jié)果中的快捷按鈕,如“應(yīng)用”、“插入到 IDE”等,開發(fā)者可以快速判斷與接受生成的單元測試代碼。

可以選擇“應(yīng)用”按鈕,將對話生成的結(jié)果,作用到對應(yīng)的代碼文件中。

可以在 IDE 編碼區(qū)域看到“應(yīng)用”這部分代碼對于當(dāng)前代碼文件的修改情況,讓研發(fā)人員快速識別到改動,快速判斷與接受。

通過這些應(yīng)用功能,我們可以看到 AI 代碼助手在單元測試中的強(qiáng)大能力,它不僅提高了開發(fā)效率,還幫助確保了軟件的質(zhì)量和穩(wěn)定性。

三、實(shí)際編碼案例解析

?針對業(yè)務(wù)代碼準(zhǔn)確生成單元測試

在真實(shí)的開發(fā)場景中,軟件的功能都是異常復(fù)雜的,一個完整的軟件功能有多個類、方法共同組成。以 Java 開發(fā)為例,一個功能的開發(fā),可能由 類的定義、Controller 控制層的方法、Server 接口定義、ServiceImpl 接口實(shí)現(xiàn)類方法、Repository 和 DTO 等等部分組成。在生成單元測試的時候,需要考慮到真實(shí)業(yè)務(wù)中的各個組件關(guān)聯(lián)性。

以上圖這個 Java 工程為例,我們需要 AI 幫我們準(zhǔn)確生成接口實(shí)現(xiàn)類 EstateServiceImpl.java 中的查詢和模糊查詢方法對應(yīng)的單元測試代碼。

我們選中 getEstates 和 getEstatesContainingText 方法之后,使用 /test 為其生成單元測試代碼。在結(jié)果中可以看到,AI 代碼助手在生成單元測試的時候,會分析代碼的工程結(jié)構(gòu),并在生成的時候智能 import 相關(guān)依賴;在生成測試代碼的時候,會結(jié)合其他文件中的類和方法定義生成測試計劃,并準(zhǔn)確構(gòu)造測試數(shù)據(jù)。

將生成的單元測試內(nèi)容,插入到指定單元測試文件中,可以直接執(zhí)行 mvn test 命令進(jìn)行單元測試驗證,可以看到這里生成的代碼可以編譯通過,并完成單元測試功能

結(jié)合業(yè)務(wù)邏輯逐步完善測試結(jié)果

??在真實(shí)的業(yè)務(wù)開發(fā)過程中,有很多測試場景都是隱晦的,它的邏輯可能并沒有直接定義在代碼內(nèi)容中,而是需要結(jié)合實(shí)際需求而定。這種場景下,需要研發(fā)人員使用對話功能告訴 AI 代碼助手這里的業(yè)務(wù)測試邏輯,繼而完善測試代碼。

?如上圖所示,我們可以通過多輪對話能力,繼續(xù)輸入真實(shí)業(yè)務(wù)場景,豐富測試的邊界條件,讓 AI 持續(xù)優(yōu)化單元測試結(jié)果。

我們將生成的擴(kuò)展內(nèi)容應(yīng)用到之前的單元測試代碼中,并執(zhí)行下這里生成的最終結(jié)果,可以看到執(zhí)行成功。

四、AI 單元測試的優(yōu)勢

從上文的實(shí)際單元測試生成場景中可以看到, AI 代碼助手可以準(zhǔn)確的生成單元測試代碼,在技術(shù)上,AI 代碼助手采用了兩個核心優(yōu)勢技術(shù),讓生成的單元測試結(jié)果更準(zhǔn)確。

?應(yīng)用上采用 AST 語法樹解析技術(shù),讓 AI 更理解項目工程,生成結(jié)果更符合業(yè)務(wù)邏輯

在單元測試過程中,最小可測試的工作單元一般為 函數(shù)、方法、類、接口等,工作單元的結(jié)果包含:返回值、系統(tǒng)狀態(tài)更改、調(diào)用第三方服務(wù)。一般情況下,工作單元的結(jié)果為以上三種的一種,或者三種的組合。

在實(shí)際的項目中,我們的測試單元很可能存在對外部的依賴,而單元測試的獨(dú)立性原則要求測試用例應(yīng)該要獨(dú)立運(yùn)行的,即我們只需要保證被測試的單元內(nèi)部邏輯正確即可,不需要真正依賴外部資源,因此我們最重要的事情是識別依賴。

?AI 代碼助手,通過 AST 語法樹解析技術(shù),在生成單元測試的時候,不單單只將單元測試的功能代碼給到模型,還會結(jié)合 AST 獲取功能代碼背后的依賴代碼,比如文件I/O操作、HTTP接口調(diào)用、RPC調(diào)用、對數(shù)據(jù)庫或者消息隊列等資源的請求代碼。將這些依賴代碼給到大模型,可以有效理解軟件工程的業(yè)務(wù)邏輯,也可以結(jié)合這些依賴代碼,在生成單元測試的時候,自動生成準(zhǔn)確有效的Mock、stub、fake 等數(shù)據(jù)。

模型上針對各類主流的單元測試框架進(jìn)行了增量訓(xùn)練,可自動識別各類主流單測框架

在單元測試場景下,各主流的編碼語言都有對應(yīng)的單元測試框架,不通框架的單元測試代碼邏輯有一定區(qū)別。 AI 代碼助手,支持根據(jù)現(xiàn)有單元測試代碼自動識別對應(yīng)的單元測試框架,在生成的時候可以遵循當(dāng)前項目已有框架生成。同時, AI 代碼助手也針對業(yè)界主流的單元測試框架進(jìn)行了增量訓(xùn)練,優(yōu)化單元測試的生成效果。

五、未來展望

雖然 AI 代碼助手目前可以做到針對單個方法/單個文件的單元測試生成,但還是依賴研發(fā)人員的對于此功能的主動使用與探索,并且當(dāng)前 AI 生成代碼還存在一些局限性:

只能做到片段式生成,多個代碼文件之間需要聯(lián)動測試的場景,覆蓋度一般

生成結(jié)果比較比較隨機(jī),多次運(yùn)行的結(jié)果可能差異較大

?AI 代碼助手即將推出批量單元測試執(zhí)行能力,旨在幫助開發(fā)者以最小成本有效提升單測覆蓋率。


項目級別的批量單元測試生成,需要強(qiáng)大的基礎(chǔ)模型能力,包括:支持豐富的上下文、模型對于代碼工程的理解和推理能力、模型的反思能力等;同時對于業(yè)務(wù)代碼本身需要非常標(biāo)準(zhǔn)規(guī)范,注釋清晰、邏輯明確。代碼解耦較好,代碼可測性較強(qiáng)。單元測試最終仍需要技術(shù)人員進(jìn)行確認(rèn),研發(fā)需要理解模型生成的單測結(jié)果,并配合模型不斷提升單測效率。

六、總結(jié)

總結(jié)來說,AI代碼助手結(jié)合騰訊混元大模型的功能,已經(jīng)在單元測試領(lǐng)域展現(xiàn)出了顯著的價值,它不僅提高了開發(fā)效率,還幫助確保了軟件的質(zhì)量和穩(wěn)定性。隨著技術(shù)的不斷進(jìn)步,AI 在單元測試中的應(yīng)用將更加廣泛和深入,為軟件開發(fā)帶來更多的便利和創(chuàng)新。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容